╔═══════════════════════╗
                       ║  AUTOSET and AUTOSCR  ║
                       ╚═══════════════════════╝

                             Version 4.02
                (Must correspond with VERSION variable)

                            (rev 02/06/04)
                            (rev 03/18/06)

           As of 03/18/06, these two very similar programs have been
      unified into one source.  The differences are controlled by the
      AUTOSCR variable at the top of the #define list.


                    Preamble to the AUTOSCR program
                =======================================

       This program is the first of a set of three programs designed
       to convert MUSEDATA Stage 2 full-score files into SCORE pmx
       files.  The program was first derived from the 3.03 version
       (rev 04/08/97) of autoset.  As with autoset, the input to the
       program are stage2 files; the output are non page specific I-files.
 
       The task of converting to SCORE is slightly different from that
       of typesetting, since it is not concerned with versatility of
       output or presentation; it is simply data conversion.  The
       autoscr program also has additional tasks to perform and will
       pass on information to the i-files which is not transferred by
       autoset.  The i-files, themselves, will have modifications that
       the music typesetting programs are not set up to read.  This
       means essentially that for purposes of data conversion, we are
       modifying the i-file format to accommodate extra data which is
       specifically related to the SCORE pmx format.

       Since versatility of size is not a consideration in data conversion,
       the autoscr program is designed to operate at one size only, namely,
       size-14.  Since we are simply concerned with transferring all data
       in the most compact manner, we will be constructing only full-score
       SCORE files.  SCORE itself has a very advanced tool-set for resizing
       scores and for extraction of parts.

       ....................................................................


                    Preamble to the AUTOSET program
                =======================================

      Program takes input file from source library file and creates
      an intermediate file

      Note: With a program as complex as this one, there are necessarily
      going to be corner cases that are too difficult or too obscure to
      handle properly.  To prevent the details of these cases from being
      "lost" in the program, there will appear from time to time
      paragraphs labled "CORNER", which decribe the situation and any
      potential limitations imposed on the program.

       ....................................................................


      Version control
      ───────────────
        09-21-93           Added 8th element to tiearr (.,TIE_FOUND) to
                             prevent program from looking twice for tie
        09-21-93           Added code to allow multiple rests when there
                             are two or more instruments all resting.
                             (one staff only)

        09-22-93           In the old version, only one wedge, one dashes
                             and one of each type of transpos could be
                             active at once.  By expanding the smusdir
                             array, we can expand this to five of each
                             type of super-object

        09-22-93           Attempting to fix several things.
                             (1) whole rest should be counted as a "pass" in
                                   computing MULTI_TRACK
                             (2) accidentals should not be repeated on a
                                   unison sounding note (mcat >= 2)

        09-23-93           Temporary ASCII data was being stored in tdata
                             which for the multiple measure case was being
                             overwritten.  Storage is now in tsdata.

        09-30-93           The sorting process for the ts(.) array has been
                             changed.  Hopefully it is now more rigorous.
                             The old algorithm is presered in comment.

        10-09-93           Autoset now works on a group of files within a
                             stage2 directory.  There is an default option
                             for the output directory, based on the group
                             being worked on.

        10-09-93           Adding the "Print suggestion" feature to the stage2
                             format.  All four slur letter pairs now are
                             interchangable.  Forcing a slur above or below
                             a note is done using a print suggestion.  Also,
                             print suggestions are now the preferred way to
                             indicate a font in a musical direction.

        10-09-93           Added 9th element to tiearr (.,TIE_FORCE) to
                             force a tie to be overhanded or underhanded

        11-11-93           Added Attribute type sub-objects.  Immediate application
                             was to add duration attribute.  Duration is expresed
                             as a ratio.  1/4 = quarter note, etc.

        01-08-94           A side effect of the bubble sort of the mf(.) array
                             (c. line 3450) was that chord tones (type 2) were
                             being separated from their principal tones (type 1).
                             The bubble sort has been replaced with a sort that
                             does not do this.

        03-19-94           Minimum distance between notes can be set with a print
                             record.  Also note value having this minimum distance
                             can be set with print record

        03-20-94           Option added to let a note with a dot be "over-printed"
                             (combined with) a note without a dot, and vice versa,
                             provided the notes are the came type (color).
                             See DOT_DIFFERENCE below.
                                 (Changed 12/24/05.  This feature is now
                                 controlled by the dot_difference_flag.)

        03-20-94           Typesetting of unisons refined.  (1) Typeset unisons are
                             allowed only when all notes of first chord are either
                             equal/above all notes of second chord, or equal/below
                             all notes of second chord.  (2) Fixed a bug where typeset
                             unisons were sometimes shifted to the right.

        03-20-94           Global tuplet print options added (tuplet_print_flag).
                             Grand staff distance option added (granddist now set
                             by print suggestion).

        03-21-94           Vertical position of musical diretions can now be
                             modified.

        03-23-94           Fixed problem of spurious accidentals being added as
                             a result of ties from the previous measure.

        03-26-94           Completely overhauled the horizonal spacing mechanism.
                             The problem was that the logic which added extra space
                             was located too late in the program, after detailed
                             information about the vertical right and left profiles
                             was lost.

        03-29-94           Improved placement of ornaments, accidentals attached
                             to ornaments, fingerings

        03-30-94           Added new component of data storage to the ts array
                             system.  Basically, we would like to be able to
                             alter the x-y position of various elements using
                             print suggestions.  To store this information, we
                             have added a string array: tsr.48(MAX_OBJECTS)

        04-07-94           Added capability to blank out notes or rests; to
                             leave space for an irest; to shift notes or rests
                             (the entire object) left or right, up or down;
                             to shift a set of figures left or right, up or
                             down.  Increased length of tsr strings to 51.

        04-26-94           Changing the way the program makes space for text.
                             In the final analysis, the placement of text and
                             the arrangement of notes over text must be done
                             by mskpage.  What is important here is that we
                             allow enough space to accommodate text, while at
                             at the same time adding as little as possible to
                             the spacing parameters.  Also implementing multiple
                             text lines at this time.

        05-27-94           Trying to correct a problem of slur placement.  There
                             seems to be some confusion over when to modify the
                             position above an object, vs. below an object.
                             For some reason I can't figure out, this information
                             was not consistant with slur tips.  Upon reflection,
                             it seems that slurs tips should determine this
                             correctly all of the time.  I'm probably missing
                             a subtle point here, so I'd better watch things
                             for a while.

        05-29-94           Under certain conditions, the NOTEDUR parameter
                             can give the wrong "time-space" increment.  We
                             cannot allow this parameter to be less than the
                             time distance (number of divisions) to the next
                             time node.  This fix may not yet be complete,
                             since we still may have wrong values for
                             Leland's score duration parameter.  Time will
                             tell.

        06-08-94           Attempting to add code to deal with repeaters.

        06-18-94           Adding feature that lets musical directions include
                             an optional offset (measured in divisions) from
                             the point where they occur in a measure.  This
                             allows things like cresc. to appear in the middle
                             of longer notes.

                             There is a slight problem in adding this feature.
                             Normally a musical direction will generate a SIGN
                             or a WORDS type object.  This translates in the
                             intermediate code to a "D" type object.  "D" type
                             objects belong to the group called "passing
                             objects," which means that the mskpage program
                             passes over them when looking for controlling
                             nodes.  The problem is that if one of this objects
                             occupies a division by itself, it should not be
                             passed over.  The solution that seems to work the
                             best is to assign "D" objects with this special
                             feature (unique division number) to a new object
                             type called "I" (isolated direction) which shares
                             all of the properties of the "F" (figure) group of
                             objects.  This does not seem to effect their
                             printing in any way, but it does seem to assure
                             that they will receive proper treatment by
                             mskpage.

                             In order to make this work in this program, we
                             need to set a special flag for SIGNS, WORDS and
                             MARKS that stand on their own division (or stand
                             with other members of this same group).  If this
                             flag is set, these elements in the ts(.) array
                             must be treated like figures in the section of
                             the program that computes space and syncopation.

        10-11-94           Added capability to specify absolute vertical position
                             of rests, etc.  Increased length of tsr string to 68.

        10-13-94           Added capability of specifying font changes for *-type
                             records with P-print suggestions using the C<columm>:
                             where the font change is to occure.  This takes
                             the !## change font instructions out of the source data
                             and puts them in the P-print suggestions where they
                             belong.

        11-21-94           Small problem:  We were using oldsct as the end of the
                             valid data in tsdata.  However, tsdata is loaded
                             according to the value of @n, which can exceed sct
                             in certain situations.  In the case where action
                             processes multiple measures, this could result in
                             data in tsdata being overwritten.  The solution
                             was to introduce a new variable old@n, which is
                             used to keep track of the end of valid data in
                             tsdata.  Since old@n tracks @n and not sct, no
                             data will be overwritten.  old@n is set to zero
                             at the same time sct is set to zero.

        01-01-95           Fix autoset so that it can serve as the source for
                             both regular autoset.z and autoset6.z (notesize = 6)

        01-02-95           The wedge spread parameter was not being properly
                             scaled.  It should be multiplied by notesize / 10.


        02-23-95           In the case where text is sporatically present (lower
                             voices of chorals, for example), there is no provision
                             to mark the end of text, when the text ends with an
                             extender (_).  Introduce new variable textconflag
                             which is turned on for notes having a simple extender
                             and off for any other text.  The combination of
                             no text and textconflag = ON is then the situation
                             we need to mark.  We will use textconflag as a bit
                             flag (i.e., bit 0 means extender in level one; bit 1
                             means extender in level two; etc.)

        04-17-95           Fix autoset so that it can serve as the source for
                             auto21.z (notesize = 21)

        04-22-95           Allow situation where notesize is odd; i.e.,
                             vpar(1) <> vpar(2) / 2.  In this case, we assume
                             2 * vpar(1) = notesize - 1

        05-29-95           Unified AUTOSET for all note sizes

        05-31-95           Code added to prevent tuplets over "partial" beams
                             from being associated with those beams.

        01-30-96           In non ISO case of two parts, where two notes are combined
                             as a chord, the "main" note was not given the right stem
                             flag.  Added line to do this.
                           When combining rests in ISO case, you need to clear last
                             line of array ts(.,.), because you will use it later for
                             collecting info on slurs
                           New code to look for cases where groups of notes might
                             be combined under the same beam.  At the moment, this
                             works only with two parts and with regular notes.

        03-04-96           Added capability to handle repeaters with two alternating
                             notes.

        09-27-96           Added capability to force rests to be printed on the middle
                             line.

        10-12-96           New feature supported:  ties that don't terminate on a note.
                             The primary use of this is when there is a first ending
                             or a da capo with a tie that refers back to an earlier
                             point in the music.  This feature is implemented using
                             a new type of musical direction ("X").

        12-24-96           Added capability to handle triple and quadruple dots

        02-02-97           Fix problem of overlapping trill extensions. Added
                           arrays pre_tsnum, pre_ctrarrf, and pre_try (pre = preliminary)

        02-19-97           Allow alternate repeaters to work on even-tuples of 6 or greater.
                             Allow slurs with alternate repeaters, when slurs start at the
                             beginning of a beam and end at the end of a beam

        02-23-97           Allow print suggestions for different kinds of printing.  Use
                             columns 2-.  Blank in column 2 = universal print suggestion.
                             Otherwise read columns 2-- until a blank is encountered.
                             Codes for selective suggestions:
 
                                "p" = parts
                                "s" = score
                                "t" = short score (piano vocal)

        02-23-97           Implement print suggestions for numbering measures.
 
        02-24-97           Fixed AUTOSET so that the accumulation of inctype
                             (the time value increment from the previous node)
                             adds up to a full measure.  This problem arrises
                             from durations that divide the quarter note by
                             factors other than 2 or 3.
 
        02-24-97           Implement Y co-ordinate positioning of wavy line (~)
                             by means of print suggestion.
 
        02-25-97           Attempting to deal with the problem of tied notes with
                             accidentals that span over to system boundaries.
                             Proposed solution is to invent a catagory of
                             "invisible" Sub-Object (type small-k), which will
                             appear in i-files, and will only be activated in
                             page files, when needed (i.e., when there is a
                             new system).
 
        03-01-97           Fix multiple accidentals on ornaments.  Allow trills
                             with wavy lines (~) to have accidentals.
 
        03-21-97           Add print suggestions for tuplets.  Square vs. round;
                             broken vs. continuous; number inside vs. outside.
 
        03-24-97           Implemented print suggestions for articulations.
                             (I think)
 
        04-08-97           Fix it so that all ornaments attached to notes of a
                             chord are printed (i.e., ornaments are not combined
                             the way articulations, accents, bowings, fermatas are).
 
        04-20-03           Implemented print suggestions for ties (as a form of
                             articulation).  This involves (1) increasing the
                             length of tsr string to 72, and (2) adding a 10th
                             element to tiearr (.,TIE_SUGG) to contain suggestions.

        04-24-03           Allowing print suggestion for extra notes of chords
 
        05-02-03           Implemented print suggestions for extension dots and
                             accidentals.  Increasing the length of tsr string to 80.
 
        05-02-03           Adding version control to print suggestions.  Hereafter
                             every print suggestion with a version control number
                             will be checked against the version of autoset running.
                             If the one's digit and the tenth's digit do not correspond,
                             a warning message will be printed.  The version also
                             contains a 100ths digit.  This allows autoset to be
                             revised in ways wherein print suggestions are not
                             affected.
 
        05-06-03           Implemented print suggestions for the shape, length and
                             position of slurs.  Length of tsr string increased to 112.
 
        05-14-03           Implementing a print suggestion for modification of the
                             first stem length of beam.  Length of tsr string increased
                             to 116
 
        05-17-03           Implementing editorial square brackets for dynamics, ornaments
                             and accents (not trill super-objects, not articulations)
 
        05-25-03           Implementing a print suggestion for preventing mskpage
                             from altering the spacings it computes in a particular
                             measure, when it is trying to justify a line.  Obviously
                             this will be over-ridden when there is only one measure
                             in the line.
 
        09-01-03           Fixing a program error.  When there was a note with multiple
                             lines of text, and the first line had an extension character
                             ("_"), autoset was ignoring the rest of the text data (i.e.,
                             the data for the remaining lines.)
 
        09-14-03           In the case where an "I" type object is being set, it can
                             happen that the variable inctype is calculated incorrectly.
                             The procedure putobj has been modified to check "I" type
                             objects for illogical inctypes.  If a correction is made,
                             a cautionary statement is issued.  This fix is somewhat of
                             a cludge.

        09-22-03           Some variables related to key and accidentals were not being
                             properly initialized at the top of the processing loop.

        10-01-03           Allowing a print suggestion for directives (* records) to set
                             the font to zero:  e.g., P   C25:f0   This will cause the
                             directive to not be printed.  This feature can be used to
                             blank directives in selected parts of a score, or allow
                             directives to appear in parts but not in the score.

        10-19-03           Corner case error:  For some reason, text records are not
                             supposed to have a "-" character in them; the solution
                             appears to be the use of "=" as a substitute for "-".
                             At c. line 14330, the substitution is made, but the code
                             neglected to take into account that "\0=" = "fi".  This
                             is now fixed.

        10-20-03           Introducing optional conversion to ligitures in text.
                             Set LIGIT = 1 to convert.

        11-04-03           Adding code to allow for job-specific print suggestions to
                             be specified by column number.

        11-16-03           Adding feature:  It is now possible to put editorial
                             parentheses around figured harmonies.

        12-09-03           Adding a new section of code which attempts to mitigate
                             somewhat the unevenness in note spacing introduced by
                             the addition of text.  This modification also adds
                             an optional second sub-parameter to the second parameter
                             (sobx) of the text record.  This second sub-parameter
                             contains the un-modified sobx for use in cases where
                             MSKPAGE or MSKPART stretches out the notes and leaves
                             enough room to keep the text at its original computed
                             location.

        12-10-03           Adding code to shorten the down stem for music with text
                             for notes on middle line of staff or on the adjacent
                             space above (B4 and C5 in the treble clef).

        12-16-03           Adding the ability for print suggestions to apply to
                             specific notesizes or to sets of note sizes.

        12-16-03           Adding the option of running AUTOSET with a note compression
                             factor.  Also trying to reduce the gradularity of note
                             distance calculations by multiplying them all by 100.
                             Introducing new variables cfactor and xmindist

        01-03-04           Adding a new print suggestion that directs autoset to generate
                             type 7 whole rests.  MSKPAGE will then be able to omit parts
                             on a system by system basis, for those parts containing only
                             type 7 whole rests.

        01-06-04           Adding a new print suggestion to implement line control
                             features.

        01-17-04           Fix a bug in program.  In order to typeset slurs, it is
                             apparently necessary to know the terminating pitch.  For
                             this reason (only), it is sometimes necessary to process
                             more than one measure at a time.  If time changes were
                             encountered in these additional measures, they were being
                             typeset at the beginning of the group instead of in their
                             proper place.  The fix is to make sure that time changes
                             encountered after the first measure are placed in the
                             ts(.) array and processed in their proper order.  Also,
                             time changes that occur at the beginning of a measure
                             must have their spn number set to 6913.

        01-17-04           Fix a bug in program.  We need to keep font changes
                             for musical directives from interferring with the
                             text of these directives.  Font changes are signalled
                             in-line by inserting "!<#>", where <#> is the new
                             font number.  We will now add a terminator "|" to this
                             code, so that font changes are now signalled by
                             "!<new font>|".

        01-19-04           The problem with inctypes that was partially fixed in
                             09-14-03 still has the problem that the inctype total
                             has be modified.  This can cause MSKPAGE to crash.
                             The current change is an attempt to fix this problem.
                             The fix is still a cludge.

        02-04-04           Adding the option of using Times Roman font for editorial
                             dynamics and the trill.

        02-06-04           Using grace note dot to typeset editorial staccato

        03-19-04           We are in the process of converting over to a new
                             system of font organization (and some new text fonts
                             as well).  For the moment, we will maintain both
                             versions of AUTOSET.  The new code will appear under
                             under the #define parameter NEWFONTS.

        04-22-04           As part of NEWFONTS, a new kerning feature has been
                             introduced -- data to be stored in new variable
                             kernmap(52,26)

        05-12-04           Adding general print suggestion to turn off the printing
                             of rests -- to be used where a blank line is supplied
                             for a continuo part

        12-18-04           Add notesize = 18 to autoset.z

        01-30-05           Adding v-type print suggestion to adjust height of text

        01-30-05           Adding treatment of "&" flag in measure records

        03-04-05           Getting rid of all code alternate to NEWFONTS

        04-10-05           In the rare case where there is text and (for reasons of
                             singers range) an alternative pitch is suggested, there
                             was a problem with the 12/09/03 code.  It was incorrectly
                             using the alternate pitch to adjust space.  The code
                             referenced here fixes this problem, but may alter the
                             original algorighm in unexpected ways, i.e., the "fix"
                             is untested.
 
        04-26-05           Adding print suggestion that allows suppression of printing
                             of a slur.  This is used when a slur lines up with a tuple
                             and the preference is to use a curved tuple bracket to
                             represent the slur (thus hopefully avoiding the clash
                             between the slur and the tuple number.  The implementation
                             of this suggestion involves the addition of a new bit
                             to the Slur super-object situation flag, sitf.
 
        05-14-05           Shifting position of staccato and spiccato marks when they
                             occur at the stem end of a note (chord)
 
        05-26-05           Expanding general print suggestions to include arbitrarily
                             fixing the position of articulations.
 
        05-28-05           New "C1:]" measure suggestion to implement mid-movement right
                             justification.  This is useful for page turns and for locating
                             repeats on system boundaries.
 
        05-29-05           Fixing a minor bug; but the change could produce unexpected
                             results.  See NOTE at change.  Also fixing a bug that in certain
                             situations reversed the order of Key-change, Time-change.
                             This change should also be watched.
 
        09-22-05           Trying to fix some minor bugs in the positioning of articulations
 
        11-02-05           Allow for special case of a grace note tied to a regular note
                             on the same division.  This permits one posible representation
                             of an arpeggiation.

        11-05-05           Fixing a minor bug; Accidentals now can attach to trills that
                             include the ~~~~~~~ super-object.
                           Also adding feature that allows accidental to follow the tr.
                             when used with the ~~~~~~~ super_object. (the U option)
 
        11-05-05           Fixing a minor bug; In the case of a key change on the grand
                             staff, cancellation naturals on the second staff where
                             being omitted.  Fix --> reset oldkey in loop
 
        11-05-05           Fixing a minor bug; Cautionary accidentals were not being
                             printed for tied-over note.  Need to over-ride the small "k"
 
        11-05-05           Adding feature:  Tuplet (brackets and numbers) can be moved
                             up or down, left or right, with a print suggestion on
                             the tuplet terminator "!"
 
        12-04-05           Fixing an obscure bug:  In certain syncopated situations
                             when processing 3 or more passes (usually on the grand
                             staff).  The DINC variable is not set correctly.  The
                             "fix" may create new problems, but only in other
                             obscure situations.  Keep a lookout!
 
        12-18-05           New feature: a single line staff may be specified by a
                             a clef code = 0 (i.e., "$     C:0")
 
        12-20-05           New feature: implementing general print suggestion j:
                             (P  C0:j#) for changing stem directions.  Default (j:0)
                             indicates "no change."
 
        12-21-05           New feature: putting "//" in the part name (line 9 of
                             the source file) will cause that part of the name that
                             follows to be put on a second line in the output.
                             Essentially, this works by inserting blanks up to
                             length 17 in place of the "//".
 
        12-20-05           New feature: implementing general print suggestion k:
                             (P  C0:k#) for setting certain operational flag (defaults are 0)
                               bit 0: (for two or more tracks)
                                  0 = allow overstrike when there a dot-difference
                                  1 = do not overstrike

        01-01-06           New feature: changing the general print suggestion r<#> to
                             be "bit" oriented, and adding a feature that allows irests
                             to globally be passed through as non-printed rest objects.
                             For the suggestion (P  C0:r<#>) the bits now indicate as
                             follows: (defaults are 0)
                               bit 0: placement of rests
                                  0 = use default placement
                                  1 = always place on middle line
                               bit 1: treatment of irests.
                                  0 = use irest as a simple "backup" command
                                  1 = treat irest as an "un-printed" rest object

        01-01-06           New feature: It is now possible to use the print suggestion
                             Px.. to ask autoset to 1) report on measure progress, and
                             2) to enter debug mode.  Specifically:
 
                             If column 3 of the command contains the letter "m",
                             then autoset will report the measures it has completed,
                             i.e., operate as if MREPORT = 1

                             If column 4 of the command contains the letter "d",
                             then autoset will operate in debug mode, i.e., as if
                             &process D were operative.

        01-01-06           CHANGING VERSION NUMBER TO 4.01
                             Reason:  We have made significant changes (improvements)
                             to the way autoset processes multi-tracks under the I:2
                             designation.  In particular, Version 4.00 accepted
                             stem-up and stem-down iso-data and rationalized these
                             into a single stem direction.  While this allowed for
                             easier creation of merged I:2 data files, it limited
                             autoset in its ability to represent precisely what
                             the encoder intended.  In Version 4.01, iso-data is
                             combined (collapsed) only when stem directions are
                             the same.  Note: files built for the older version of
                             autoset can still be processed as intended by including
                             the print suggestion "P   C0:j3".

        01-04-06           There is an on-going problem when repeaters are combined
                             with super-objects.  I have crafted a "fix" for the case
                             of simple repeaters + tuples, but there is still much
                             work to be done here.

        01-06-06           I have allowed notes with repeaters to have articulations
                             on the first note (I think).

        01-06-06           Extending the general print suggestion d<#> to include
                             Ending super-objects.

        01-06-06           Extending the general print suggestion a<#> for articulations.

        01-07-06           Adding the tremulo ornament to the group which includes
                             trills, turns, mordents, etc.  Allowing print suggestions.

        01-07-06           There is a bug in the way print suggestions interact with
                             transpositions.  The "fix" works, but may expose other
                             problems.

        01-07-06           Adding some warnings re: bad format of musical directions
                             (* type records).

        01-13-06           Implementing arpeggios

        01-15-06           Allowing slurs to end on a repeater (first note in group)

        01-15-06           Attempting to allow repeaters on groups of alternating notes
                             of size 6, 12, and 24; i.e., notes pairs represented with
                             extension dots.  Additions done "on the fly" and not
                             fully reasoned or fully checked out.  Keep an eye on it.

        02-19-06           We need to add a feature that allows for different types of
                             note heads to be printed.  The immediate need is for an "x"
                             for "cymbal crash," but there are many other percussion and
                             non-standard shapes.  Philosophically, this could be
                             approached in two ways: either this information could be
                             "hard coded" as is the note size (i.e., in column 17), or
                             it could be done with a print suggestion.  I am planning to
                             take the second route, and here is why.  Size, it could be
                             argued should be hard coded, because it is often used to
                             indicate editorial vs. original information, and we have
                             chosen to hard code this distinction.  Note shape, on the
                             other hand, does not change pitch or duration, but rather
                             indicates (at most) something about the means by which a
                             note is played and about the sound.  It would be nice to
                             hardcode this information, but I don't see an easy way to
                             do this.  Columns 17 to 22 are designated for note
                             description, and they are fully taken up.  The only way
                             would be to add more codes in column 17, and since printed
                             duration is already contained here (comprising a dimension
                             with 11 elements, we would rapidly run out of codes, if we
                             tried to overlay another dimension of shape.  The alternative
                             is to use a print suggestion, and here we have a viable
                             solution.  There is already a print suggestion for modifying
                             the printing of note, rest and figure objects.  It's
                             designation is "C1:".   The code "p" in this catagory
                             accounts for one of the 4 bytes available, and of the 8 bits
                             in this byte, only 4 are currently in use.  This means that
                             we could introduce a new catagory "s", which would have
                             4 bits available to it.  This could accommodate 15 exotic
                             note shapes, which should be enough.

        03-04-06           Revising AUTOSET so that in default mode multiple rests will
                             be generated only when typesetting parts.  Global print
                             suggestion m<#> can be used to over-ride default.
                             C0:m0 = no multi rests;  C0:m1 = generate multi-rests

        03-07-06           Adding the ability to set multiple rests up to mdouble, mdotted
                             mheavy2, and mheavy3.  Note: this feature is normally for
                             parts only.

        03-13-06           Removing type 6 and type 7 Symbol Objects (whole rests as
                             symbols) and replacing them with type 9 Rest Objects with
                             inc = 10000 or inc = 10001.  The new MSKPAGE requires this.
                           Also, don't even process for "multi rests" unless the
                             multirest_flag = 1 (Normally Parts only).

        03-18-06           Combining the source codes for AUTOSCR and AUTOSET.
                           Also, adding certain features of each of these programs
                             to the other.  In the case of AUTOSET, we are adding
                             the capability to communicate pitch and track information
                             to the output via attribute records (A records)

        03-25-06           Adding various "@" records for tranmitting source and
                             analysis information.

        08-23-06           Adding editorial accidentals to key signature

        09-13-06           In the soprano clef, the placement algorithm was placing
                             flats too low on the staff.  The current "fix" covers only
                             the placement of flat, not flat cancellations.

        11-20-06           Adding feature that allows a slur over a set of repeated
                             notes with repeater, provided that the slur covers all
                             the notes in the group and that there are no chords
                             in the repeated pattern.

        11-26-06           Fixing a minor bug in the placement of slurs.

        11-26-06           Adding feature to global print suggestion C0:k that
                             asks that new key signatures be printed out even
                             when they are no different from the existing one.

        11-26-06           Adding feature to allow chords (double stops) with
                             two colors of notes

        11-26-06           Fixing a minor bug in the placement of extension
                             dots when combining parts on a single staff

        10-14-07           Adding code to allow autoscr to combine notes on
                             a single beam when there are irests present.  This
                             situation comes up when there is a change from
                             single parts to a combined part within a measure.

        10-15-07           Adding code to put out "silent" key change nodes.
                             No difference in display output.  This addition
                             just clears up a corner case bug in the mskpage
                             process (the easiest fix in this case).

        10-15-07           Adding code to deal with rests with capital letter
                             note types.  With rests, capital letter note types
                             are used to indicate rests which might be taken
                             out if the take out variable wrest = 1 and an
                             entire line in a score has nothing but rests.
                             To signal a capital letter rest, autoset/autoscr
                             puts out a jtype = r instead of the usual
                             jtype = R.  The mskpage/spaging program knows
                             how to deal with this and always outputs a
                             capital "R" to the page specific files.

        10-24-07           Adding grobal print suggestion for setting musical
                             font in $ records.  Default defined by DEFAULT_DTIVFONT.
                             The mdirfont variable is now used only for text in
                             musical directives.  Its default is DEFAULT_MDIRFONT.

        10-25-07           Fixing a bug in the autoscr process.  Accidental shift
                             units are scaled differently in SCORE than in Dmuse.
                             The conversion is 25 SCORE units = vpar(2) Dmuse units.

        10-28-07           There is a minor bug in autoset that we fix here.  In the
                             case where notes are combined into chords, the print
                             suggestions for the separate notes were being or-ed
                             together, producing unpredictable results.  Actually,
                             this is bad encoding on the part of the encoder, and
                             should probably be flagged with a WARNING.  But in
                             any case, the print suggestions should be combined in
                             a more intelligent way.

        11-02-07           Adding a new global flag, suppress_key, which suppresses
                             the printing of the key signature.  This to be used
                             in timpani parts where the timplani are tuned to
                             pitches with accidentals (e.g., B-flat and F).   The
                             flag is set by bit-4 of the "k" global suggestion.

        11-10-07           I uncovered a major problem in the implementation of print
                             suggestions for articulations.  First of all, byte 1 of
                             the tcode string was not being set properly.  This was
                             causing getpxpy to return null values for the various
                             suggestions.  In addition, the interference section for
                             the code was uniformly preempting the placement
                             articulations irrespective of print suggestions.  I have
                             fixed (I think) the problem for the case of spiccatos,
                             but have not checked the results for other articulations.

        11-15-07           There is an obscure spacing difference between autoset and
                             autoscr having to do with the typsetting of irest.  I think
                             it comes up when the irest has a dot.  The fix here is an
                             untested cludge, but it seems to work.

        11-19-07           Adding a new global suggestion to allow the minimum space
                             between notes to be altered.  P   C0:h<#> where # is a
                             percentage of the default (= 9 for notesize 14).

        11-24-07           Fixing a small detail having to do with how autoscr
                             computes P3 and P10

        12-08-07           There is a problem with the continuation of the ~~~ wavy
                             line when there is more than one pass.  The solution is
                             to make ctrflag a one-dimention array indexed by passnum.
                             This change may facilitate the printing multiple wavy
                             lines in a measure on a staff, but it also may introduce
                             some other problems.  Keep an eye on this.

        12-14-07           Fixing a logical problem that goes way back.  The problem is with
                             the array claveax(.), which is used to reset the measax(.,.)
                             array, which in turn is used to determine which accidentals
                             are used in front of notes.  When there is a key change in
                             the music, claveax(.) is adjusted AT THE TIME IT IS TYPESET.
                             But the spelling of the notes is determined while the
                             ts(.,.) array is being constructed.  If there is a slur over
                             a key change, the ts(.,.) array continues to be built with
                             the old claveax(.) array.  What we need is a new array
                             tclaveax(.), which is set to claveax(.) whenever a there is
                             a new build of the ts(.,.) array, but which can be changed
                             if there is a key change.  Then measax(.,.) can be reset
                             from tclaveax(.) and the note spellings will reflect the
                             new key.  I have made these changes, and the program seems
                             to work.  Keep an eye on this, though.

        01-01-08           Adding a minor new feature:  The "c" option for print
                             suggestion C26:  The "c" option is a varient of the
                             "a" option.  It converts a single set of repeated
                             notes to a repeater and adds a dot after the combined
                             note value.  Strictly speaking, the resulting duration
                             is 50% too long, but the notation provides a convenient
                             way of representing repeated triplets (or some multiple
                             of triplets) without having to put the tuple number
                             above the repeater.  The actual duration of the note
                             for spacing purposes is not altered.

        01-26-08           Fixing a small bug in connection with editorial accents

        02-03-08           Attempting to add a new feature (autoset only), which is
                             the 'R' type musical designation; a rehearsal number of
                             letter with a box drawn around it.  The trick will be
                             getting the box size and placement right

        04-19-08           There is an error in the way single track processing handles
                             the minimum spacing for dotted rests.   This occurs at
                             approximately lines 12300 ++.  The computed minimum space
                             is too large, because the right-hand margin gr(.,.) is made
                             too large due to some double counting.  I don't want to change
                             this code, however, because it will alter the horizontal
                             spacing, which can (and sometime does) change the way mskpage
                             does the system breaks (an example of being locked in by
                             an error).  The problem is not severe, because the minimum
                             space is often exceed anyway by the real space.  Fine.
                             But this creates another problem, namely when autoscr computes
                             the space for rests in a multi-track measure, it always
                             uses the multi-track code (irests are ignored by autoset
                             in this situation).  This means that the i-file spacings
                             generated by autoset and autoscr may be slightly different;
                             and this can lead to different system breaks.  I have
                             added some code at approximately lines 14350 ++ to simulate
                             the single track error.  The code is quite cludgey and may
                             not work all of the time.

        04-19-08           The single track error describe above also causes the dot following
                             sixteenth and smaller rests to be placed too far to the right.
                             I added a small bit of code to partially fix this problem,  The
                             code does not change the horizontal spacing formula.

        04-22-08           Adding a new feature: the back tie.  Since the position of this
                             character depends only on the note object, it is implemented as
                             a subobject.  J = overhand back tie; K = underhand back tie.
                             For purposes of print suggestions, the back tie is handled like
                             a standard ornament.  This means back ties may be applied to
                             multiple notes on a chord, but it also means that a note with
                             a back tie may have at most one ornament attached to it.  Since
                             back ties are rare (second endings, etc.), this should not be
                             a problem.  Note: for the moment, back ties are not converted
                             to SCORE files.

        05-01-08           Fixing an obscure problem with slurs.  In the case where an
                             "inside" slur is desired (e.g., underhanded in an upper part
                              on a stave), the automatic slur adjustment algorithm tries
                              to make this slur go below everything on the staff, which
                              usually works, but not always.  This code change implements
                              a new global print suggest C0:g<#> which can be used to
                              defeat (turn off) the automatic slur adjustment feature.
                              In this case other slur print suggestions should be used
                              to position the slur.

        06-04-08           Fixing an obscure problem with the placement of accidentals
                              on notes with repeaters.  I changed the limits on the gl(.,.)
                              array so that the accidental does "see" the repeaters.
                              Note: this fix might introduce some overlap in some situations.

        06-04-08           Expanding from three to four the number of notes allowed in a
                              chord when multiple passes are used.  (I think this works)

        09-21-08           Expanding the repeater feature to include sub-groups (secondary beam)
                              of 3 and 6.  This comes up in the case of repeated triplets.   At
                              the moment, I don't have a way of making this work with the tuple
                              numbers.  I just hope the new code does't throw off the common
                              cases.  Keep an eye on this.

        10-08-08           The first version of autoset permitted up to 15 different dynamic
                              combinations.  At the time (c. 1988), this seemed like plenty,
                              so four bits were allocated in the ts(.) array for this purpose.
                              Now, it seems, we have exceeded this limit (Beethoven writes ffp
                              in the 7th symphony).  In this code update, I have garnered another
                              three bits, allowing for another 8 dynamic combinations.  Only
                              one of which is used at this point (ffp).  We have space for 7
                              more in the current setup.  The ts(.) element SUBFLAG_1 actually
                              has two more bits available (before it goes negative), so we
                              could in theory add another 24 dynamic combinations.  Lets
                              wait and see what's needed.
 
        10-24-08           Adding a new print suggestion for breaking up a multi-measure rest
                              "P  C1:f"  The suggest must follow directly after the "measure"
                              record where the break is to occur.  It applies only to the
                              typesetting of parts.  If this measure (barline) is also to serve
                              as a system break (P  C1:]), then the system break suggestion
                              should follow after the multi-measure break.

        10-29-08           There was a problem in the way single whole-measure rests were being
                              compiled for parts.  For multiple rests, field 8 (the distance
                              increment flag) of the following barline object is irrelevant;
                              but for single whole-measure rests, the mskpage program tries to
                              use that flag in the normal way.  When more than one part is being
                              typeset, this can result in an accumulation error.  Since typesetting
                              multiple parts in a system is a highly useful feature (e.g., for
                              for comparison purposes), I coded a fix for this problem -- which
                              seems to work, but beware.  It may impact the spacing of single
                              whole-measure rests.

        11-18-08           The dynamic combination "ff" has been spaced a bit too widely.  Adding
                              a new horizontal parameter hpar(140) to deal with this.

        11-18-08           Also at this time, I am raising slightly the number over a multiple
                              rest bar for notesize = 21.

        12-31-08           Working on the implementation of notesize = 16.

        01-02-09           Adding a provision for larger note heads in the size 16 font
                             This effects the following parameters.  Altimately, these
                             parameters are fixed in the proofpar library; but for the
                             time being, I want to keep this feature in this program

                               hpar(51) =  width of quarter note (approximately)
                               hpar(82) =  width of black note (for typesetting)
                               hpar(83) =  width of whole note (for typesetting)
                               hpar(84) =  width of breve note (for typesetting)

        01-12-09           New general print suggestion, a subset of k.  If k & 0x10 > 0,
                             the slur pairs "{ }" and "z x" will be interpreted as editorial.
 
        01-12-09           Fixing a minor bug in the implementation of horizontal print
                             suggestions.  When the node is isolated, the modification must
                             be in the position of the word sub-object, not the object.

        01-12-09           Encountering a new dynamic sign in Mozart of all places, mfp.
                             We will use some of the new space created 10-08-08.

        02-02-09           Adding a new element to general print suggestion C0:k
                             Bit 5: set = typeset all new clef signs in full size
                                          (for use in multi-singer recitatives).

        02-02-09           We can now use the sequence "\+" to indicate an inline
                             "space" character.  This is useful in music text
                             underlay.

        03-10-09           It turns out that conductors have varying preferences
                             when it comes to the format and appearance of conducting
                             scores.  For example, when two instruments appear on a
                             single staff, some conductors want to see both musical
                             lines represented all of the time, vs. showing only the
                             active musical lines.  An acceptable variation on this
                             is to show a single line when the instruments are playing
                             in unison.  Others would rather see the score kept as clean
                             as possible, with the use of 1. and 2. and a single line
                             of music when only one of the two instruments is playing.
                             For this reason, it is necessary to implement a second
                             score-type group, called skore, whose use we will, by
                             convention, assign to the more complete (and busy)
                             representation.

        03-15-09           There needs to be a way to disable the feature where
                             rests are collapsed in the two instrument isorhythmic
                             case.  We will use bit 2 of the global print suggestion
                             P  C0:r  for this.  The situation comes up when typesetting
                             scores with complicated two instrument parts.

        03-16-09           Encountering a new dynamic sign in Beethoven, sff.
                             We will use some of the new space created 10-08-08.

        11-23-09           Fixing a small bug that developed when I tried to improve
                             obx spacing with repeaters.

        11-27-09           Adding the "@  SCORECON pitch transposition" option for
                             applying a post pitch modification to the P6 parameter.


     Program options


#define    XPOS_FIXED     1
                               /* with Beethoven, try 1 first, then 0; with Haydn, use 1

#define    DISP_DISK      "j"

#define    VERSION    "4.02"
                               /* Version 4.00 defined 05/02/03
                               /* Version 4.01 defined 01/01/06
                               /* Version 4.02 (current version) defined 02/03/08 (new data file in musprint)
#define    AUTOSCR        0

#define    PGROUP         "scrcon"

#define    SFZ            0
                               /* SFZ            = 1:  print sfortzando as sfz

#define    DOT_DIFFERENCE 1    (12/24/05 now controlled by dot_difference_flag)
                               /* DOT_DIFFERENCE = 1:  don't allow overstrike

#define    SUB_EDIT       1
                               /* SUB_EDIT       = 0:  do not distinguish between
                               /*                        original and editorial data
#define    NO_EDIT        0
                               /* NO_EDIT        = 1:  do not process editorial data
#define    ROMAN_EDIT     0
                               /* ROMAN_EDIT     = 1:  use Times Roman font for
                               /*                        editorial marks: tr, dynamics
#define    OLD_REPEATERS  1
                               /* OLD_REPEATERS  = 1:  use half notes instead of quarters
#define    CUSTOM_PAR     1
                               /* allows use of custom parameters, for whatever reason
                               /* see code at CUSTOM_PAR
#define    LIGIT          1
                               /* LIGIT          = 1:  convert ffl, ffi, ff, fl, fi in
                               /* text subobjects to ligitures
                               /* see code at CUSTOM_PAR
#define    DEFAULT_DTIVFONT    37
#define    DEFAULT_MDIRFONT    31
                               /* default font for musical directions
#define    BIG16          0
                               /* 01/02/09  Wide version of size 16 note heads

#define    REPORT4        0
#define    MREPORT        0
                               /* 01/01/06  This feature can also be activated by
                               /* using the print suggestion "Pxm."
#define    OBJ_REPORT     0

#define    TRUE           0
#define    FALSE          1

      Actual Characters

#define    DOT_CHAR      44


      Descriptive Definitions

#define    TIE_SNUM       1
#define    TIE_NTYPE      2
#define    TIE_VLOC       3
#define    TIE_FHDIS      4
#define    TIE_FSTEM      5
#define    TIE_NDX        6
#define    TIE_STAFF      7
#define    TIE_FOUND      8
#define    TIE_FORCE      9
#define    TIE_SUGG      10
#define    TIE_ARR_SZ    10
                                 /* 04/20/03 new 10th element for tiearr

#define    FIG_SNUM       1
#define    FIG_HOFF1      2
#define    FIG_HOFF2      3
#define    FIG_READY      4

#define    REG            1
#define    GRACE          2
#define    CUE            3
#define    CUEGRACE       4

#define    BM_SNUM        1
#define    BM_CNT         2
#define    BM_READY       3
#define    BM_STEM        4
#define    BM_TUPLE       5
#define    BM_SIZE        6
#define    BM_SUGG        7
#define    BM_SZ          7

#define    SL_SNUM        1
#define    SL_YSHIFT      2
#define    SL_XSHIFT      3
#define    SL_NEXTSNUM    4
#define    SL_BEAMF       5
#define    SL_SUGG        6
#define    SL_SIZE        6

#define    TU_SNUM        1
#define    TU_Y1          2
#define    TU_Y2          3
#define    TU_FSTEM       4

#define    TYPE           1
#define    DIV            2
#define    CLAVE          3
#define    AX             4
#define    TEMP4          4
#define    NTYPE          5
#define    DOT            6
#define    TUPLE          7
#define    STAFFLOC       8
#define    SPACING        9
#define    STEM_FLAGS    10
#define    BEAM_FLAG     11
#define    BEAM_CODE     12
#define    LOCAL_XOFF    13
#define    SUPER_FLAG    14
#define    SLUR_FLAG     15
#define    SUBFLAG_1     16
#define    SUBFLAG_2     17
#define    VIRT_NOTE     18
#define    SORTPAR1      18
#define    SORTPAR2      19
#define    TEMP2         19
#define    GLOBAL_XOFF   19
#define    TEXT_INDEX    20
#define    PASSNUM       21
#define    BACKTIE       22
#define    NOTE_DUR      23
#define    DINC_FLAG     24
#define    VIRT_STEM     25
#define    ED_SUBFLAG_1  26
#define    ED_SUBFLAG_2  27
#define    STAFF_NUM     28
#define    NUM_STAVES    28
#define    MULTI_TRACK   29
#define    TEMP1         30
#define    SPN_NUM       30
#define    OBY           31
#define    SLUR_X        32
#define    NODE_SHIFT    33
#define    TRACK_NUM     34
#define    BASE_40       35
#define    NOTE_DISP     36
#define    AX_DISP       37
#define    AUG_DOTS      38
#define    TSR_POINT     39
#define    TS_SIZE       42

      ts(.) Array positions for arpeggio variables  (note doublings with other flags)

#define    ARPEG_FLAG    16
#define    ARPEG_TOP     26
#define    ARPEG_BOTTOM  27

#define    TSR_LENG     116

#define    NUMBER_OF_FIG  3
#define    FIG_SPACE      4
#define    FIG_DATA       5
#define    MIN_FIG_SPAC  20
#define    FIG_DUR       23

#define    SIGN_POS       3
#define    SIGN_TYPE      4
#define    SUPER_TYPE     5
#define    FONT_NUM       6
#define    WEDGE_OFFSET   7
#define    S_TRACK_NUM    8
#define    WEDGE_SPREAD  10
#define    POSI_SHIFT1   11
#define    ISOLATED      12
#define    POSI_SHIFT2   13

#define    TIME_NUM       3
#define    DOLLAR_SPN     5
                              /* (New 01/17/04)
#define    DIVSPQ         3

#define    CLEF_NUM       3
#define    CLEF_FONT      4
#define    TRANS_FLAG     5
#define    CLEF_STAFF_POS 6

#define    BAR_NUMBER     3
#define    BAR_TYPE       4
#define    REPEAT         5
#define    BACK_ENDING    6
#define    FORW_ENDING    7
#define    BAR_FLAGS      8
#define    M_NUMBER      10

#define    REGULAR        1
#define    HEAVY          2
#define    DOTTED         3
#define    DOUBLE_REG     5
#define    REG_HEAVY      6
#define    HEAVY_REG      9
#define    DOUBLE_HEAVY  10
#define    DOUBLE_DOTTED 15

#define    WEDGES         1
#define    DASHES         2
#define    OCT_UP         3
#define    OCT_DOWN       4
#define    DBL_OCT_UP     5
#define    DBL_OCT_DOWN   6
#define    NORMAL_TRANS  13

#define    NOTE           1
#define    XNOTE          2
#define    REST           3
#define    CUE_NOTE       4
#define    XCUE_NOTE      5
#define    CUE_REST       6
#define    GR_NOTE        7
#define    XGR_NOTE       8
#define    NOTE_OR_REST   8
#define    FIGURES        9
#define    BAR_LINE      10
#define    SIGN          11
#define    WORDS         12
#define    MARK          13
#define    CLEF_CHG      14
#define    DESIGNATION   15
#define    METER_CHG     16
#define    DIV_CHG       17
#define    AX_CHG        18
#define    P_SUGGESTION  19

#define    MUSICAL_DIR   11
#define    IREST         12
#define    BACKSPACE     13

#define    SEGNO          1
#define    PED            2
#define    END_PED        3
#define    LETTER_DYNAM   4
#define    RIGHT_JUST_STR 5
#define    CENTER_STR     6
#define    LEFT_JUST_STR  7
#define    TIE_TERM       8
                                  /* TIE_TERM added 10-12-96
#define    REH_MARK       9
                                  /* REH_MARK added 10-12-96
#define    BELOW          1
#define    ABOVE          2

#define    HEAD           0
#define    TAIL           1

#define    FULLSIZE       0
#define    CUESIZE        1

#define    THIRTY_SECOND  4
#define    SIXTEENTH      5
#define    EIGHTH         6
#define    QUARTER        7
#define    HALF           8
#define    WHOLE          9
#define    BREVE         10
#define    SLASH8         0
#define    ARPEGGIO      33
                                 /* ARPEGGIO added 01/13/06
#define    UP             0
#define    DOWN           1
#define    SINGLE_NOTE    0
#define    CHORD          1

#define    NO_BEAM        0
#define    END_BEAM       1
#define    START_BEAM     2
#define    CONT_BEAM      3

#define    OFF            0
#define    ON             1

*     Parametric Definitions

#define    MAX_STAFF      2
#define    MAX_TIES      16
#define    MAX_FIG        4
#define    MAX_PASS      10
#define    MAX_OBJECTS 1000
#define    MAX_M        400

*     Other Definitions

#define    DUMMY_VALUE 10000
#define    INT1000000  1000000
#define    INT10000    10000
#define    INT100        100
#define    INT9000      9000
#define    BHPAR1         30
#define    MAX_MEAS     2000

*     Process parameters

*process D
            /* 01/01/06  This feature can also be activated by
            /* using the print suggestion "Px.d"

*

   str infiles.12(100),pgroup.12
   str file.100,out.280,line.180,temp.180,lib.30,temp2.160,temp3.160,temp4.160,temp5.20
   str line2.180,slurstr.160,slurlet.1,slurover.80,slurunder.80
   str inlib.100,outlib.100,outfile.100
   str claves.7,numbers.10,accs.3
   str note.4,jtype.1,codes.12
   str ttext.180,msg.60,xbyte.2                            /* ttext lengthened to 180 04/22/04
   str tcode.4(MAX_M),tdata.80(MAX_M,2)
   str sobl.120(30),tsdata.100(MAX_OBJECTS)
   str mname.60,tname.60,wname.80,sourcename.80,partname.80
   str tsr.TSR_LENG(MAX_OBJECTS)                           /* 05/14/03 expanded length to 116
   str version.4                                           /* 05/02/03
   str mrest_line.200                                      /* New 03/07/06

   int tv1(MAX_M),tv2(MAX_M),tv3(MAX_M),tv4(MAX_M)
   int tv5(MAX_M)                                          /* New 01/17/04
   int tvar1,tvar2,tiecnt
   int supcnt,supnums(12)
   int mf(256),beampar(4,MAX_PASS,BM_SZ),mf2(120)          /* 05/14/03 expanded BM_SZ to 7
   int multichk(3,MAX_PASS,MAX_STAFF)
   int tiearr(MAX_TIES,TIE_ARR_SZ),slurar(8,SL_SIZE),tuar(4,MAX_PASS,4)
   int figarr(MAX_FIG,4)
   int sitf,super_flag,slur_flag,subflag_1,subflag_2
   int spc(255),nsp(33),claveax(50),measax(4,50)           /* 06/04/08 expanding measax to (4,50)
   int tclaveax(50)                                        /* New 12/14/07
   int zak(2,7),wak(9),hpar(200),vpar(200),bvpar(35),vpar20
   int a,d,e,g,h,i,j,k,m,s,y,z
   int @a,@b,@c,@d,@e,@n,old@n
   int f1,f2,f3,f4,pmode
   int notesize,mtfont,twfont,beamfont,curfont,mdirfont,dtivfont
   int olddivspq,divspq
   int cline(MAX_STAFF),clef(MAX_STAFF),clave,key
   int a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16
   int save_a4
   int c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13,c14,c15,c16,c17
   int t1,t2,t3,t4
   int x1,x2,y1,y2,z1
   int olda1,unison_flag,sugg_flg,sugg_flg2
   int beamdata(4,MAX_PASS,31),beamcode(31)
   int passpar(MAX_PASS)
   int firstsp,tfirstsp,emptyspace(MAX_STAFF,45)
   int ts(MAX_OBJECTS,TS_SIZE)
   int sct,oldsct,maxsct,divpoint,mrest,measnum,totdiv,cuediv,mdiv,qflag
   int figdiv,esnum,smusdir(30,4)
   int tsnum(MAX_PASS),ctrarrf(MAX_PASS),try(MAX_PASS)
   int pre_tsnum(MAX_PASS),pre_ctrarrf(MAX_PASS),pre_try(MAX_PASS)
   int ntype,f8,inctype,jcode,pcode,nodtype,passtype,passsize,stem
   int firstoff,sigflag
   int oby,sobx,soby,sobcnt,snum
   int sobx2                                  /* added 12/09/03
   int obx1,obx2,oby1,oby2
   int c8flag(MAX_STAFF),transflag(MAX_STAFF),tuflag,passnum,chorddur,spn
   int ctrflag(MAX_PASS)                      /* made into an array 12/08/07
   int mindist
   int tnum,tden,abflg,nstaves
   int ssize,scnt,debug_point
   int vflag,mcat,sflag,granddist,outpnt,tword_height
   int note_dur
   int minshort
   int global_tpflag
   int tpflag,xposi_shift,yposi_shift
   int save_xposi_shift                                       /* added 01/12/09
   int pcontrol,px,py,pyy,pxx
   int putobjpar
   int repeater_flag,repeater_flag2,repeater_case
   int repeater_dot_flag                                      /* added 01/01/08
   int repeater_dot_flag2                                     /* added 09/21/08
   int chord_spread,mdir_offset
   int font_changes(10,2),changecnt
   int textconflag
   int min_space                                              /* added 11/19/07
   int slur_adjust                                            /* added 05/01/08

   bstr outslurs.8
   label E(20),T(6),SS(21),PSUG(20),TPF(5),TPFF(5),ADJS(5)    /* expanding PSUG 05/01/08
   label R1(14)
   table X(10000),Y(30000)

   Variables added 6-19-93 for processing slurs

   int profile(100,2)
   int sgroup(13,3),nsgroups
   int curvedata(8,4,8)
   int curve


   Variables added 5-27-93 for pseudo typesetting of simultaneous notes

   int npasses,thispass,passcnt(MAX_PASS,3)
   int pitchcnt(10)
   int ndata(20,11)
   int pcnt
   int clashes(10,10)
   int tgroup(10),ntgroups
   int printpos(10)
   int ps_passcount(2)
   int gl(2,45),gr(2,45),oldgr(2,45)
   int pseudo_gr(2,45)
   int pseudo_gl(2,45)
   real r1,r2,r3,r4

   Variables added 4-27-94 for determining text position

   int ttextcnt
   str ttextarr.80(6)
   str xbytearr.2(6)

   Variables added 6-08-94 for working or repeaters

   str chord_tones.4(10)

   int chordsize,last_chordsize,chordsize2
   int checkoff(10)
*
   int p,x,obx,dv1,dv2,dv3,dv4

   Variables added 9-27-96 for controlling position of rests

   int restplace,restplace2

   Variables added 02-23-97 for determining range of print suggestions
     and numbering measures; and the inctype accumulation problem

   str job_type.1
   int m_number
   int inctype_rem

   Variables added 12/09/03 for trying to even out notes with text underlay

   int nspace(MAX_M,8),org_c4

   Variables added 12/16/03 for running AUTOSET with a compression factor

   int cfactor,xmindist

   Variable added 01/03/04 for generating option type 7 whole rests

   int wrest

   Variable added 10/15/07 for generating optional smaller rests

   int opt_rest_flag

   Variable added 01/19/04 to fix the accumulation of inctypes

   int fix_next_inctype

   Variables added 03/19/04 to implement NEWFONTS organization

   str XFontstr.76(12)
   str kernfiles.360

   int XFonts(12,19)
   int Fspacex(90)
   int revsizes(24)
   int nsizes(12)
   int sizenum
   int kernmap(52,26)

   Variables added 05/12/04 to implement print suggestion to turn
     off the printing of rests (for empty continuo lines).

   int restoff


   Variables added 01/30/05 to implement print suggestion to adjust
     height of text under staff

   int text_flag
   int text_loc

   Variable added 05/26/05 to implement arbitrary fixed placement
     of articulations

   int art_flag

   Variable added 12/18/05 to implement single line staff

   str LL.1
   int single_line

   Variable added 12/20/05 to implement stem change flag

   int stem_change_flag
   bstr tbit1.2000,tbit2.2000

   Variable added 12/24/05 to implement various operational flags

   int dot_difference_flag

   Variable added 01/01/06 to set various new flags

   int irest_flag
   int mreport_flag
   int debug_flag
   int ligit_flag
   int xdata_flag
   int scr_flag
   int rest_flag(MAX_PASS)
   int tracknum_flag

   Variable added 01/06/06 to allow the d<#> print suggestion to include Endings

   int ending_height

   Variables added 01/13/06 to implement arpeggios

   int arpeg_flag
   int arpeg_top
   int arpeg_bottom

   Variables added 03/04/06 to for controlling the setting of multi-rests

   int multirest_flag

   Variables added 11/26/06 to allow reprinting of existing key signature
                            and chords with two colors
                            Also fixing a minor bug in printing extension
                            dots

   int key_reprint_flag
   int mixed_color_flag
   int old_c2

   Variables added 10/14/07 to allow autoscr to combine notes under one beam
                            when there are irests present.

    int beam_fixup_cnt
    int beam_fixup_arr(100,2)

   Variable added 11/02/07 to allow suppression of the key signature

    int suppress_key

   Variables added 02/03/08 to allow typesetting of boxes around rehearsal numbers

    int box_flag
    int font_base,font_height,zero_height

   Variable added 01/12/09 to allow "{ }" and "z x" to represent editorial slurs

    int in_line_edslur

   Variable added 02/02/09 to control the "large clef" option

    int large_clef_flag

   Variable added 03/15/09 to permit the disabling of rest collapse

    int rest_collapse

   Variables added 03/20/03 for additional code required by autoscr

   int measuremap(MAX_MEAS,5)      /* 1 = number of tracks
                                   /* 2 = number of gaps    3 = pointer to data
                                   /* 4 = number of divspm  5 = number of divspq
   int trackstave(MAX_MEAS,9,3)    /* trackstave data
   int timegaps(15000,3)
   int barnum,tgpnt,staves,track,staff,durflag,barnum2,opbarnum
   int trackdivpnt(9)
   int scr_qwidth
   int how_much_mrest(2)
   int composer_num
   int track_flag
   int track_assign(9)
   int instrument_number
   int transposition

   str jscrdat.80,kscrdat.100
   str header1.180
   str header2.180
   str header3.180
   str composer.80
   str comp_names.80(20)

   Variable added 11/27/03 for additional code required by autoscr

   int pitch_mod


┌──────────────────────────────────────────────────────────────┐
│        Description of arrays not described elsewhere         │
└──────────────────────────────────────────────────────────────┘

   Description of tiearr(MAX_TIES,TIE_ARR_SZ)

     This is an array for collecting information on ties.  The
   program allows up to MAX_TIES such simultaneous ties (first
   dimension of the array).  The second dimension contains the
   following attributes:

       tiearr(TIE_SNUM)  = super-object number for this tie
       tiearr(TIE_NTYPE) = note type: 1 = note, 2 = xnote, 4 = cue, 5 = xcue, etc.
       tiearr(TIE_VLOC)  = location on staff of tied notes
       tiearr(TIE_FHDIS) = horizontal displacement of first note
                               head from its object (chords only)
       tiearr(TIE_FSTEM) = stem flag for first note
       tiearr(TIE_NDX)   = ts() index for first note in tie
       tiearr(TIE_STAFF) = staff number (0 or 1) for first note in tie
       tiearr(TIE_FOUND) = tie found flag
       tiearr(TIE_FORCE) = tie force flag
       tiearr(TIE_SUGG)  = print suggestions for altering tie position (added 04/20/03)

     Note:  It can happen that a note is tied in both directions
   out of the measure (e.g. pedal points).  In this situation, we
   will need to use the information in the old tiearr before
   constructing a new one.  Since we cannot deposit the tie
   super-object until we have deposited the terminating note
   object, and since we cannot deposit this note object without
   knowing the new super-object number for the forward tie, we must
   increment snum and store this number somewhere before writing
   out the note object.  We will use tv4(.) to store this number.
   This also has a baring on how ties are handled within the
   measure.  When a tie flag is encountered, snum is incremented
   and stored in tv4(.).  tv4(.) is filled with ties from the top
   note down.  After any backward ties are dealt with, a free slice
   of tiearr is identified and filled.  The pointer to this slice
   of tiearr may be put in ts(22) (after old ties are taken care
   of).  If the other end of this tie is encountered within the
   measure (as determined by ts(22)), then the information in
   tiearr is used with current information to construct the
   super-object.


   Description of figarr(MAX_FIG,4)

     This is an array for collecting information on continuation
   lines for figures.  The program allows up to MAX_FIG figures, and
   each of these levels may have a continuation line.  The first
   dimension is therefore MAX_FIG; the highest level is 1 and the
   lowest level is MAX_FIG.  (In this version 3.0, MAX_FIG is 4)
   The second dimension contines the following attributes:

       figarr(FIG_SNUM)  = super-object number for this continuation
       figarr(FIG_HOFF1) = horizontal off-set from first object
       figarr(FIG_HOFF2) = horizontal off-set from second object
       figarr(FIG_READY) = completion flag:  set = array completed


   Description of beamdata(4,MAX_PASS,31)

     Note: At the moment, there is a structural reason why the third
     dimension of beamdata cannot exceed 31.  This is because
     beampar(.,.,BM_STEM) stores stem directions as bits.

     This is an array for collecting information on the beams that
   connect notes together.  The first dimension tells whether this
   information is for (1) regular notes, (2) grace notes to regular
   notes, (3) cue notes, or (4) grace notes to cue notes.  The
   second dimension tells the pass number for this beam.  The
   third dimension contains the beamcodes for the various notes
   under the beam.

     The beamcode is a number between 1 and 666661.  It describes the
   structure of the beam for this note/chord.  This version (3.0) of
   the program supports beams up to 256th notes.  The ones column of
   the beamcode is for eighth notes, the tens column for sixteenth
   notes, etc.  The digits have the following meaning:

                         1 = continued beam
                         2 = begin beam
                         3 = end beam
                         4 = forward hook
                         5 = backward hook
                         6 = repeater character
                         7 = begin repeated beam
                         8 = end repeated beam


   Description of beampar(4,MAX_PASS,BM_SZ)           05/14/03 expanded BM_SZ to 7

     In addition to beamdata, there are seven other parameters
   related to beams.  These parameters are represented in the
   array beampar as follows:

       beampar(BM_SNUM)  = super-object number for the beam
       beampar(BM_CNT)   = note counter for beam
       beampar(BM_READY) = flag that signals that a beam is complete
                               and should be put out.
       beampar(BM_STEM)  = stem flags for notes under beam
       beampar(BM_TUPLE) = tuplet flag, which relates to the beam
                               in the following ways:
            a. BM_TUPLE is set to (1 + stem) when the first note of
               a beam is a tuplet
            b. BM_TUPLE must be cleared after a beam is processed
            c. if processing a beam, if BM_TUPLE is > 0 and if
               end of tuplet bit is set, then process tuplet
               with this beam (i.e. use no bracket and put
               tuplet number over the beam in the middle.

       beampar(BM_SIZE)  = size of beam (full size vs. cue size)
       beampar(BM_SUGG)  = suggestion for modifying length of first stem of beam  New 05/14/03

   Description of slurar(8,SL_SIZE)

     This is an array for collecting information on slurs between
   two notes.  This program allows up to four simultaneous slurs,
   and four dotted slurs (hence the first dimension = 8).  The
   second dimension contains the following elements:

       slurar(SL_SNUM)     = super-object number for this slur
       slurar(SL_YSHIFT)   = shift in y co-ordinate of the first
                                note of the slur
       slurar(SL_XSHIFT)   = shift in x co-ordinate of the first
                                note of the slur
       slurar(SL_NEXTSNUM) = super-object number for next slur
                                (or zero)
       slurar(SL_BEAMF)    = beam flag:  0 = slur does not start on a beam
                                         1 = slur starts on a stem-up beam
                                         2 = slur starts on a stem-down beam
       slurar(SL_SUGG)     = print suggestion for beginning of slur  (05/06/03)

     Note:  There are some similarities between the handling of
   ties and the handling of slurs.  It can happen that a note will
   have one or more slurs ending and/or starting on it.  In this
   case, as in the case of ties, the terminating super-objects
   cannot be written until the object is written, and the object
   cannot be written until the super-object numbers for the new
   slurs are known.  This means that we must establish these
   numbers and save them before destroying the contents of the
   slurar for the old slurs.  This is the purpose for the NEXTSNUM
   element in slurar.  It is the super-object number for a forward
   slur.  After the backward slur is written, and at the time the
   new elements of slurar are to be written, this number is moved
   from slurar(SL_NEXTSNUM) to slurar(SL_SNUM).


   Description of tuar(4,MAX_PASS,4)

     This is an array for collecting information on tuplet groups.
   The first dimension tells whether this information is for
   (1) regular notes, (2) grace notes to regular notes, (3) cue
   notes, or (4) grace notes to cue notes.  The second dimension
   tells the pass number for this tuplet group.  The elements of
   the third dimension are as follows:

       tuar(TU_SNUM)  = super-object number
       tuar(TU_Y1)    = y co-ordinate of the first object
       tuar(TU_Y2)    = y co-ordinate of the terminating note
                            head of the first object
       tuar(TU_FSTEM) = bits 0-7: stem flag of the first note
                        bits 8-15: bracket flags (0 = no bracket)

     Note:  Since it is not possible for a note to belong to two
   tuplet groups at once, we do not have the problem present in
   ties and slurs.  There is a short-cut to processing that has been
   mentioned in connection with beams, and which should be mentioned
   here also.  At processing time (when tuplet process bit is set),
   we should check to see if beampar(.,.,BM_TUPLE) for this pass
   is set.  If it is, then we should do nothing; the tuplet will
   be processed along with the beam and without a bracket.  If
   beampar(.,.,BM_TUPLE) is clear, then we must process the tuplet
   using a bracket.

   Handling of the long trill

     The long trill is a simple super-object.  However, there may
   be several long trills in a measure-group.  Therefore we need to
   store this information for each pass.

   Let us assume up to MAX_PASS passes.  Then each of the parameters
   associated with long trills (tsnum, ctrflag, and try) will be a one
   dimentional array type variable.

   The parameters associated with long trills are as follows:

       ctrflag(.) = wavy line continuation flag (made into an array 12/08/07)

         tsnum(.) = super-object number of long trill (0 = no
                       long trill present)
 
       ctrarrf(.) = situation flag   1 = no "tr" before long ~~~
                                     2 = "tr" start, no accidental
                                     3 = "tr" start, with sharp
                                     4 = "tr" start, with natural
                                     5 = "tr" start, with flat

           try(.) = vertical displacement from associated object

   To deal with the case of overlapping trills (one long trill ends
   where the next begins), we have introduced the arrays:

         pre_tsnum(.) = prelimary storage for tsnum(.)
       pre_ctrarrf(.) = prelimary storage for ctrarrf(.)
           pre_try(.) = prelimary storage for try(.)

   for storing temporarily the associated values of tsnum, ctrarrf
   and try.


   Description of smusdir(30,4)

       There are actually 6 musical direction super-objects: wedges,
   dashes, octave-up transposition, octave-down transposition, 15-up
   transposition, and 15-down transposition.  We may encounter these
   in any one of up to 5 passes.  Therefore the first dimension is
   (super-object type - 1) * 5 + pass-number.  If there is no pass
   number, then the first available row starting at 1 will be used
   (i.e., assume pass 1 first, then pass 2, etc.).  If the row for
   a particular pass is in use, then use the next higher one, etc.
   If no rows are available, this should halt the program.

       Desciption of the second element:

             smusdir(.,1)  = snum (0 = inactive, > 0 = active)
             smusdir(.,2)  = spread (Wedges)
                           = word space (Dashes)
                           = 0 (Oct-up)
                           = 1 (Oct-down)
                           = 2 (15-up)
                           = 3 (15-down)
             smusdir(.,3)  = offset (Wedges)
                           = font number (Dashes)
                           = x-offset (Transpositions)
             smusdir(.,4)  = vertical offset from top of staff

    Vertical Parameters    vpar(.)
    -------------------

  vpar(1)  =  one   vertical note space
  vpar(2)  =  two      "       "  spaces
  vpar(3)  =  three    "       "    "
  vpar(4)  =  four     "       "    "
  vpar(5)  =  five     "       "    "
  vpar(6)  =  six      "       "    "
  vpar(7)  =  seven    "       "    "
  vpar(8)  =  eight    "       "    "
  vpar(9)  =  nine     "       "    "
  vpar(10) =  ten      "       "    "
  vpar(11) =  vertical shift for printing multiple rest ends
  vpar(12) =  vertical correction of dot position, if on staff line
  vpar(13) =  height parameter for beams
  vpar(14) =  shift in height for multiple beams
  vpar(15) =  cutoff of severe up-down pattern under beam
  vpar(16) =  vertical space between beams
  vpar(17) =  fudge factor for two/more slanted beams on staff lines
  vpar(18) =  fudge factor for one slanted beam on staff lines
  vpar(19) =  maximum rise allowed for beam on one staff line
  vpar(20) =  minimum rise allowed for beam crossing two staff lines
  vpar(21) =  minimum rise allowed for beam crossing 3 staff lines
  vpar(22) =  vertical shift for printing hooks and beams
  vpar(23) =  shift down for printing italic 8 under treble clef
  vpar(24) =  minimum stem length that triggers adding to 16th stem

  vpar(31) =  vertical shift for printing add-flags
  vpar(32) =  (un-used)
  vpar(33) =  first level of time words
  vpar(34) =  (un-used)
  vpar(35) =  (un-used)
  vpar(36) =  vertical shift for printing grace size add-flags
  vpar(37) =  adjustment f/raising 16th beams because of short stems
  vpar(38) =  minimum for sum of two stems under 2-note beam
  vpar(39) =  amount to extend stems under 2-note beam (s. vpar(38))
  vpar(40) =  height of horizontal ending lines

    vertical parameters (continued)   vpar(.)

  vpar(41) =  length of vertical hooks on ending lines
  vpar(43) =  height of signet sign above staff lines
  vpar(44) =  height above staff for words, wedges
  vpar(45) =  height below staff for words, wedges
  vpar(46) =  height above staff for 8ve
  vpar(47) =  height below staff for 8ve
  vpar(48) =  height of figures
  vpar(49) =  position of first figure
  vpar(50) =  height of spiccato character
  vpar(51) =  height of horizontal ~~~~
  vpar(52) =  height of turn
  vpar(53) =  height of tr. trill character
  vpar(54) =  height of shake
  vpar(55) =  height of mordent
  vpar(56) =  height of accidental over ornament
  vpar(57) =  height of horizontal accent
  vpar(58) =  height of vertical accent
  vpar(59) =  height of harmonic character
  vpar(60) =  height of thumb position character
  vpar(61) =  height of down bow
  vpar(62) =  height of up bow
  vpar(63) =  height of fermata
  vpar(64) =  height of tuplet number
  vpar(65) =  vertical shift for adding sixteenth grace rest flag
  vpar(66) =  default distance between staves of grand staff
  vpar(67) =  amount to lengthen flag stem with repeater if note is on a space (stem up)
  vpar(68) =  amount to lengthen flag stem with repeater if note is on a line  (stem up)
  vpar(69) =  location for first repeater on flag stem if note is on a space (stem up)
  vpar(70) =  location for first repeater on flag stem if note is on a line  (stem up)
  vpar(71) =  amount to lengthen flag stem with 2  repeaters if note is on a space (stem down)
  vpar(72) =  amount to lengthen flag stem with >2 repeaters if note is on a space (stem down)
  vpar(73) =  amount to lengthen flag stem with 2  repeaters if note is on a line  (stem down)
  vpar(74) =  amount to lengthen flag stem with >2 repeaters if note is on a line  (stem down)
  vpar(75) =  location for first repeater on flag stem if note is on a space (stem down)
  vpar(76) =  location for first repeater on flag stem if note is on a line  (stem down)
  vpar(77) =  maximum absolute stopping point for quarter stem with repeater (stem up)
  vpar(78) =  mimimum absolute stopping point for quarter stem with repeater (stem down)
  vpar(79) =  slight lengthening of quarter stem with repeater
  vpar(80) =  more extra lengthening of quarter stem with one repeater
  vpar(81) =  location of first repeater on quarter stem
  vpar(82) =  location of tuple number above note or quarter stem with repeaters
  vpar(83) =  location of tuple number above eight stem with repeaters

        New vertical parameters 05/17/03

  vpar(84) =  vertical shift up for printing square brackets for editorial dynamics
  vpar(85) =  vertical shift up for printing square brackets for editorial trill
  vpar(86) =  vertical shift up for printing square brackets for editorial accidentals
  vpar(87) =  vertical shift up for printing square brackets for turn ornament
  vpar(88) =  vertical shift up for printing square brackets for shake ornament
  vpar(89) =  vertical shift up for printing square brackets for mordant ornament
  vpar(90) =  vertical shift up for printing square brackets for horizontal accent
  vpar(91) =  vertical shift up for printing square brackets for vertical accent

        New vertical parameter 11/16/03

  vpar(92) =  vertical shift up for printing small parentheses around figures
  vpar(93) =  vertical shift up for printing large parentheses around figures



  vpar(101) = vertical displacement to first line of text


    Horizontal Parameters    hpar(.)
    ---------------------

  hpar(1)  =  shift following accidental natural
  hpar(2)  =  shift following accidental sharp
  hpar(3)  =  shift following accidental flat
  hpar(4)  =  minimum distance between notes
                   dotted note to note ratio  = 12 / 10
                   triplet note to note ratio =  9 / 10
                   double note to note ratio  = 13 / 10
                      (cf. determine spacing)
  hpar(5)  =  distance from beginning of staff lines to 1st character
  hpar(6)  =  shift following accidental natural-sharp
  hpar(7)  =  shift following accidental natural-flat
  hpar(8)  =  shift after big clef sign
  hpar(9)  =  shift following sharp or natural in key signature
  hpar(10) =  shift following accidental double sharp
  hpar(11) =  shift following flat in key signature
  hpar(12) =  shift after key signature
  hpar(13) =  shift if no key signature or key change
  hpar(14) =  shift following common or cut time signature
  hpar(15) =  shift following accidental double flat
  hpar(16) =  shift to middle of double digit time signature
  hpar(17) =  shift to middle of single digit time signature
  hpar(18) =  shift after time signature
  hpar(19) =  shift for printing staccato and spiccato at stem end (New 05/14/05)
  hpar(20) =  shift for large number
  hpar(21) =  half shift for large number
  hpar(22) =  shift before printing multiple rest
  hpar(23) =  shift after printing multiple rest
  hpar(24) =  shift before printing whole measure rest
  hpar(25) =  shift for complete whole measure rest
  hpar(26) =  space taken up by up flag
  hpar(27) =  extra shift for dot under flag
  hpar(28) =  extra shift after note with stem-up flag
  hpar(29) =  minimum separation between previous object and accidental
  hpar(30) =  shift for dot after half or whole rest
  hpar(31) =  shift for dot after quarter or smaller rest
  hpar(32) =  shift for dot after whole note or larger
  hpar(33) =  shift for dot after half note or smaller note
  hpar(34) =  horizontal correction of dot position, if on staff line
  hpar(35) =  minimum space following projecting flag
  hpar(36) =  space before bar line
  hpar(37) =  space after bar line
  hpar(38) =  length of beam hook character
  hpar(39) =  placement of movement word
  hpar(40) =  shift for the first natural/flat of a double accidental
  hpar(41) =  gap between ending line and measure line
  hpar(42) =  gap between end of long trill and next object
  hpar(43) =  distance between repeat sign and bar line
  hpar(44) =  space between light bar and light bar
  hpar(45) =  space between heavy bar and light bar, or light bar and heavy bar, or two heavy bars
  hpar(46) =  space between end of wedge and dynamic
  hpar(47) =  space between end of 8ve and next object
  hpar(48) =  space between end of continuation and bar line
  hpar(49) =  space add to left side of note heads to further separate them
                from previous objects (implemented, because the separation
                of hpar(29) alone is not enough between note heads)

  hpar(51) =  width of quarter note (approximately)
  hpar(52) =  shift of small italic 8 for octave treble clef
  hpar(53) =  approximate width of grace note
  hpar(54) =  right shift for adding sixteenth rest flag
  hpar(55) =  not used
  hpar(56) =  length of standard beam character
  hpar(57) =  back shift before concatination character
  hpar(58) =  space between words
  hpar(59) =  back shift before last "__" of continuous underline
  hpar(60) =  width of dynamic letter p
  hpar(61) =  width of dynamic letter m
  hpar(62) =  width of dynamic letter f
  hpar(63) =  width of dynamic letter s
  hpar(64) =  width of dynamic letter z
  hpar(65) =  width of dynamic letter r
  hpar(66) =  width of number figure
  hpar(67) =  width of small plus figure
  hpar(68) =  width of small x figure
  hpar(69) =  width of two-plus figure
  hpar(70) =  width of figured sharp
  hpar(71) =  width of four-plus figure
  hpar(72) =  width of five-plus figure
  hpar(73) =  width of six-slash figure
  hpar(74) =  width of seven-slash figure
  hpar(75) =  width of figured natural
  hpar(76) =  width of figured flat
  hpar(77) =  overlap if figure continuation line
  hpar(78) =  right shift if slur interferes with stem
  hpar(79) =  actual thickness of light bar line
  hpar(80) =  thickness of dot
  hpar(81) =  actual thickness of heavy bar line
  hpar(82) =  width of black note (for typesetting)
  hpar(83) =  width of whole note (for typesetting)
  hpar(84) =  width of breve note (for typesetting)
  hpar(85) =  space between stems (for typesetting)
  hpar(86) =  width of big clef sign (approximate)
  hpar(87) =  width of whole rest and half rest
  hpar(88) =  width of quarter rest and eight rest
  hpar(89) =  right shift for adding sixteenth grace rest flag
  hpar(90) =  width of stem
  hpar(91) =  shift to second dot of double dot
  hpar(92) =  width of common and cut time glyph
  hpar(93) =  width of bar line
  hpar(94) =  minimum extra shift, when accidental occurs on note of minimum space
  hpar(95) =  "chip" off of note shape
  hpar(96) =  width of heavy bar line
  hpar(97) =  standard spacing between grace notes
  hpar(98) =  amount by which repeater protrudes from stem
  hpar(99) =  offset of repeater for eighth notes (stem up)
  hpar(100) = offset of repeater for eighth notes (stem down)
  hpar(101) = offset of repeater for quarter notes (stem down)
  hpar(102) = offset for printing tuple number above stem with repeater
  hpar(103) = offset for printing tuple number above note with repeater
  hpar(104) = back shift for printing two tuple numbers
  hpar(105) = forward shift for printing second of two tuple numbers
  hpar(106) = forward shift for printing second of two leger lines (for note on line)
  hpar(107) = forward shift for printing second of two leger lines (for note on space)

        New horizontal parameters 05/17/03

  hpar(108) =  width of editorial dynamic letter p
  hpar(109) =  width of editorial dynamic letter m
  hpar(110) =  width of editorial dynamic letter f
  hpar(111) =  width of editorial dynamic letter s
  hpar(112) =  width of editorial dynamic letter z
  hpar(113) =  width of editorial dynamic letter r
  hpar(114) =  backup to print square bracket for editorial p   [p...
  hpar(115) =  backup to print square bracket for editorial m   [m...
  hpar(116) =  backup to print square bracket for editorial f   [f...
  hpar(117) =  backup to print square bracket for editorial s   [sf
  hpar(118) =  backup to print square bracket for editorial r   [rf
  hpar(119) =  shift to print square bracket following editorial f   f]
  hpar(120) =  shift to print square bracket following editorial p   p]
  hpar(121) =  shift to print square bracket following editorial z   z]
  hpar(122) =  backup to print square bracket for editorial tr  [tr]
  hpar(123) =  shift to print square bracket following editorial tr  [tr]
  hpar(124) =  backup to print square bracket for editorial accidental
  hpar(125) =  shift to print square bracket following editorial accidental
  hpar(126) =  backup to print square bracket for turn ornament
  hpar(127) =  shift to print square bracket following turn ornament
  hpar(128) =  backup to print square bracket for shake ornament
  hpar(129) =  shift to print square bracket following shake ornament
  hpar(130) =  backup to print square bracket for mordant ornament
  hpar(131) =  shift to print square bracket following mordant ornament
  hpar(132) =  backup to print square bracket for horizontal accent
  hpar(133) =  shift to print square bracket following horizontal accent
  hpar(134) =  backup to print square bracket for vertical accent
  hpar(135) =  shift to print square bracket following vertical accent

        New horizontal parameters 11/16/03

  hpar(136) =  backup to print small left parenthesis in front of figure
  hpar(137) =  shift to print small right parenthesis after figure
  hpar(138) =  backup to print large left parenthesis in front of figures
  hpar(139) =  shift to print large right parenthesis after figures

        New horizontal parameters 11/18/08 etc.

  hpar(140) =  width of dynamic letter f in ff combinations

     Vertical parameters
     -------------------

      loop for i = 1 to 10
        vpar(i) = i * 8
      repeat
      vpar(11) = 4
      vpar(12) = 7
      vpar(13) = 42
      vpar(14) = 7
      vpar(15) = 30
      vpar(16) = 13
      vpar(17) = 6
      vpar(18) = 9
      vpar(19) = 7
      vpar(20) = 22
      vpar(21) = 27
      vpar(22) = 4
      vpar(23) = 64
      vpar(24) = 40

      loop for i = 1 to 24
        vpar(i) = vpar(i) * notesize / 16
      repeat

      vpar(31) = 14 * notesize + 8 / 16
      vpar(32) = 0                           /* was 8
      vpar(33) = 5 * notesize / 3
      vpar(34) = 0                           /* was 121
      vpar(35) = 0                           /* was 15
      vpar(36) = 12 * notesize + 6 / 16
      vpar(37) = 3 * notesize - 8 / 16
      vpar(38) = 84 * notesize / 16
      vpar(39) = 15 * notesize / 16
      vpar(40) = 3 * notesize
      vpar(41) = 3 * notesize / 2
      vpar(43) = 5 * notesize / 2
      vpar(44) = 5 * notesize / 2
      vpar(45) = 8 * notesize
      vpar(46) = 4 * notesize
      vpar(47) = 10 * notesize
      vpar(48) = 3 * notesize / 2
      vpar(49) = 7 * notesize
      vpar(50) = notesize
      vpar(51) = notesize
      vpar(52) = 3 * notesize / 2
      vpar(53) = 2 * notesize
      vpar(54) = 3 * notesize / 2
      vpar(55) = 3 * notesize / 2
      vpar(56) = 4 * notesize / 3
      vpar(57) = 3 * notesize / 2
      vpar(58) = 3 * notesize / 2
      vpar(59) = 3 * notesize / 2
      vpar(60) = 3 * notesize / 2
      vpar(61) = 3 * notesize / 2
      vpar(62) = 9 * notesize / 4
      vpar(63) = 2 * notesize
      vpar(64) = 3 * notesize / 2
      vpar(65) = 11 (for notesize 14)  4 (for notesize 6)
      vpar(66) = 10 * notesize
      vpar(67) = 8 (for notesize 14)
      vpar(68) = 5 (for notesize 14)
      vpar(69) = 21 (for notesize 14)
      vpar(70) = 18 (for notesize 14)
      vpar(71) = 2 (for notesize 14)
      vpar(72) = 1 (for notesize 14)
      vpar(73) = 6 (for notesize 14)
      vpar(74) = 5 (for notesize 14)
      vpar(75) = 21 (for notesize 14)
      vpar(76) = 17 (for notesize 14)
      vpar(77) = 19 (for notesize 14)
      vpar(78) = 24 (for notesize 14)
      vpar(79) = 2  (for notesize 14)
      vpar(80) = 1  (for notesize 14)
      vpar(81) = 19 (for notesize 14)
      vpar(82) = 17 (for notesize 14)
      vpar(83) = 33 (for notesize 14)

        New vertical parameters 05/17/03

      vpar(84) =  5 (for notesize 14)
      vpar(85) =  8 (for notesize 14)
      vpar(86) =  8 (for notesize 14)
      vpar(87) =  6 (for notesize 14)
      vpar(88) =  5 (for notesize 14)
      vpar(89) = 10 (for notesize 14)
      vpar(90) =  7 (for notesize 14)
      vpar(91) =  6 (for notesize 14)
      vpar(92) =  7 (for notesize 14)
      vpar(93) =  3 (for notesize 14)

      vpar(101) = 101

     Horizontal parameters
     ---------------------

      hpar(1) = 17
      hpar(2) = 21
      hpar(3) = 18
      hpar(4) = 34
      hpar(5) = 6
      hpar(6) = 38
      hpar(7) = 35
      hpar(8) = 60
      hpar(9) = 18
      hpar(10) = 24
      hpar(11) = 15
      hpar(12) = 19
      hpar(13) = 4
      hpar(14) = 55
      hpar(15) = 35
      hpar(16) = 25
      hpar(17) = 11
      hpar(18) = 33
      hpar(19) = 8                    /* New 05/14/05
      hpar(20) = 24
      hpar(21) = 12
      hpar(22) = 10
      hpar(23) = 30
      hpar(24) = 30
      hpar(25) = 110
      hpar(26) = 15
      hpar(27) = 12
      hpar(28) = 5
      hpar(29) = 9
      hpar(30) = 36
      hpar(31) = 24
      hpar(32) = 37
      hpar(33) = 29
      hpar(34) = 2
      hpar(35) = 44
      hpar(36) = 5
      hpar(37) = 25
      hpar(38) = 18
      hpar(39) = 80
      hpar(40) = 17
      hpar(41) = 10
      hpar(42) = 32
      hpar(43) = 15
      hpar(46) = 20
      hpar(47) = 14
      hpar(48) = 30
      hpar(49) = 3

      loop for i = 1 to 50
        hpar(i) = hpar(i) * notesize / 16
      repeat

      hpar(44) = 6 (for notesize = 14)
      hpar(45) = 5 (for notesize = 14)

      hpar(51) = 18 * notesize + 8 / 16
      hpar(52) = 7 * notesize + 2 / 7
      hpar(53) = 13 * notesize + 2 / 16
      hpar(54) = 4
      hpar(55) = 0     /* not used, formerly 80
      hpar(56) = 30
      hpar(57) = 3
      hpar(58) = 16 (for notesize 14)
      hpar(59) = 0 (not used)
      hpar(60) = 23 (for notesize 14)
      hpar(61) = 25 (for notesize 14)
      hpar(62) = 19 (for notesize 14)
      hpar(63) = 12 (for notesize 14)
      hpar(64) = 18 (for notesize 14)
      hpar(65) = 15 (for notesize 14)
      hpar(66) = 15 (for notesize 14)
      hpar(67) = 13 (for notesize 14)
      hpar(68) = 13 (for notesize 14)
      hpar(69) = 22 (for notesize 14)
      hpar(70) = 11 (for notesize 14)
      hpar(71) = 22 (for notesize 14)
      hpar(72) = 22 (for notesize 14)
      hpar(73) = 20 (for notesize 14)
      hpar(74) = 14 (for notesize 14)
      hpar(75) = 9  (for notesize 14)
      hpar(76) = 11 (for notesize 14)
      hpar(77) = 3 * notesize / 2
      hpar(78) = 4 * notesize / 3
      hpar(79) = 2 (for notesize 14)
      hpar(80) = 6 (for notesize 14)
      hpar(81) = 7 (for notesize 14)
      hpar(82) = 19 (for notesize 14)
      hpar(83) = 24 (for notesize 14)
      hpar(84) = 28 (for notesize 14)
      hpar(85) = 6 (for notesize 14)
      hpar(86) = 38 (for notesize 14)
      hpar(87) = 27 (for notesize 14)
      hpar(88) = 15 (for notesize 14)
      hpar(89) = 3 (for notesize 14)
      hpar(90) = 2 (for notesize 14)
      hpar(91) = 13 (for notesize 14)
      hpar(92) = 25 (for notesize 14)
      hpar(93) = 2  (for notesize 14)
      hpar(94) = hpar(2) >> 2 (4 for notesize 14)
      hpar(95) = hpar(85) + hpar(90) >> 1 (4 for notesize 14)
      hpar(96) = 7  (for notesize 14)
      hpar(97) = 21 (for notesize 14)
      hpar(98) = 11 (for notesize 14)
      hpar(99) = 1  (for notesize 14)
      hpar(100) = hpar(82) - hpar(99)
      hpar(101) = hpar(82) - hpar(90)
      hpar(102) = 10 (for notesize 14)
      hpar(103) = 2  (for notesize 14)
      hpar(104) = 9  (for notesize 14)
      hpar(105) = 17 (for notesize 14)
      hpar(106) = 3  (for notesize 14)
      hpar(107) = 1  (for notesize 14)

        New horizontal parameters 05/17/03

      hpar(108) = 18 (for notesize 14)
      hpar(109) = 21 (for notesize 14)
      hpar(110) = 15 (for notesize 14)
      hpar(111) = 10 (for notesize 14)
      hpar(112) = 12 (for notesize 14)
      hpar(113) = 12 (for notesize 14)
      hpar(114) =  8 (for notesize 14)
      hpar(115) =  8 (for notesize 14)
      hpar(116) = 11 (for notesize 14)
      hpar(117) =  6 (for notesize 14)
      hpar(118) =  6 (for notesize 14)
      hpar(119) =  7 (for notesize 14)
      hpar(120) =  0 (for notesize 14)
      hpar(121) =  3 (for notesize 14)
      hpar(122) = 11 (for notesize 14)
      hpar(123) = 21 (for notesize 14)
      hpar(124) =  8 (for notesize 14)
      hpar(125) = 13 (for notesize 14)
      hpar(126) =  7 (for notesize 14)
      hpar(127) = 28 (for notesize 14)
      hpar(128) =  8 (for notesize 14)
      hpar(129) = 27 (for notesize 14)
      hpar(130) = 10 (for notesize 14)
      hpar(131) = 27 (for notesize 14)
      hpar(132) =  9 (for notesize 14)
      hpar(133) = 23 (for notesize 14)
      hpar(134) =  9 (for notesize 14)
      hpar(135) = 21 (for notesize 14)
      hpar(136) =  7 (for notesize 14)
      hpar(137) = 15 (for notesize 14)
      hpar(138) = 10 (for notesize 14)
      hpar(139) = 15 (for notesize 14)
      hpar(140) = 17 (for notesize 14)


   Description of tsr.TSR_LENG(MAX_OBJECTS)         /* 05/14/03: size changed to 116

      The purpose of the tsr strings is to store print suggestion data
      for the note object and for sub-objects in the note field 32-43.

      Note Object
      ───────────

          byte1:   bit 0 = control

                              0 = no modification of data (default in
                                    99.9% of all cases)
                              1 = possible modification somewhere
 
                bits 1-4 = print modification code

                              0 = no modification
                              1 = turn off all sub-objects
                              2 = turn off all sub-objects
                                    but print an extension dot

                            3-7 = eliminate tie if there is one
                              3 = print object, no extension dot
                              4 = print object, include extension dot
                              5 = double note length, no extension dot
                              6 = double note length, include extension dot
                              7 = quadruple note length, no extension dot
 
          byte2:   x-y active flags

                     0x01: active flag (0 = inactive)
                     0x02: 0 = x position is relative
                           1 = x position is absolute
                     0x04: 0 = y position is relative
                           1 = y position is absolute

          byte3:   modification of horizontal position (from default)

                     if byte3 >= 128, move notation to the right
                                      by the amount (byte3 - 128)
                     if byte3 < 128,  move notation to the left
                                      by the amount (128 - byte3)
                     if byte3 = 0,    do nothing

          byte4:   modification of vertical position (from default)

                     if byte4 >= 128, move notation down by the
                                      amount (byte4 - 128)
                     if byte4 < 128,  move notation up by the
                                      amount (128 - byte4)
                     if byte4 = 0,    do nothing



      Sub-objects in the Note Field 32-43
      ───────────────────────────────────

      At the moment, there are 19 code catagories for which data    05/02/03
      can be stored.  Each of these catagories requires 4 bytes.
      The data stored in each byte is as follows:

          byte1 -- Normal case:
 
                   bit 0 = control

                              0 = no modification of data (default in
                                    99.9% of all cases)
                              1 = possible modification somewhere in this byte
 
                   bit 1 = major location change flag

                              0 = no change in position relative
                                    to staff (default)
                              1 = determine position relative to staff
                                    from bit 2

                   bit 2 = position relative to staff

                              0 = place notation above staff
                              1 = place notation below staff

                   bit 3 = print flag for score

                              0 = print notation in score (default)
                              1 = don't print notation in score

                   bit 4 = print flag for non-score (parts)

                              0 = print notation in non-score (default)
                              1 = don't print notation in non-score

                   bit 5 = parentheses flag for score

                              0 = no action (default)
                              1 = surround notation with parentheses
                                    in score

                   bit 6 = parentheses flag for non-score (parts)

                              0 = no action (default)
                              1 = surround notation with parentheses
                                    in non-score (parts)

          byte1 -- Ties:
 
                   modification to length of tie (end position)

                     if byte1 >= 128, make length longer by the
                                      amount (byte1 - 128)
                     if byte1 < 128,  move length shorter by the
                                      amount (128 - byte1)
                     if byte1 = 0,    do nothing to length

          byte2:   x-y active flags

                     0x01: active flag (0 = inactive)
                     0x02: 0 = x position is relative
                           1 = x position is absolute
                     0x04: 0 = y position is relative
                           1 = y position is absolute

          byte3:   modification of horizontal position (from default)

                     if byte3 >= 128, move notation to the right
                                      by the amount (byte3 - 128)
                     if byte3 < 128,  move notation to the left
                                      by the amount (128 - byte3)
                     if byte3 = 0,    do nothing

          byte4:   modification of vertical position (from default)

                     if byte4 >= 128, move notation down by the
                                      amount (byte4 - 128)
                     if byte4 < 128,  move notation up by the
                                      amount (128 - byte4)
                     if byte4 = 0,    do nothing


          The code catagories are as follows:
 
              1 = legato(_), staccato(.), line with dot(=)
              2 = spiccato:     (i)
              3 = accents:      horizontal(>), vertical(V), inverted vertical(A)
 
              4 = single ornaments:  turn(r), trill(t), shake(w), wavy line (~)
                                       mordent(M), delayed turn(k)
              5 = second single ornament

              6 = bowing:       up-bow(v), down-bow(n)
              7 = harmonic:     string harmonic(o)
              8 = thumb-open:   thumb(Q), open-string(0)
              9 = finger1:      finger code level 1
             10 = finger2:      finger code level 2
             11 = finger3:      finger code level 3
             12 = finger4:      finger code level 4
             13 = finger5:      finger code level 5

             14 = dynamics:     any dynamic string

             15 = upright fermata:   (F)
             16 = inverted fermata:  (E)
             17 = tie:               (-)      04/20/03:  added tie to list
             18 = dots:              (column 18)
             19 = accidentals:       (column 19)


      Slurs in the Note Field 32-43    05/06/03
      ─────────────────────────────

      At the moment, there are 8 code catagories for which data
      can be stored.  Each of these catagories requires 4 bytes.

      For codes 20-23 = starting slurs "([{z" the data stored
      in each byte is as follows:

          byte1:   modification of horizontal start of slur (from default)

                     if byte1 >= 128, move start of slur to the right
                                      by the amount (byte1 - 128)
                     if byte1 < 128,  move start of slur to the left
                                      by the amount (128 - byte1)
                     if byte1 = 0,    do nothing

          byte2:   modification of vertical start of slur (from default)

                     if byte2 >= 128, move start of slur down by the
                                      amount (byte2 - 128)
                     if byte2 < 128,  move start of slur up by the
                                      amount (128 - byte2)
                     if byte2 = 0,    do nothing

          byte3:   modification of horizontal position of slur (from default)

                     if byte3 >= 128, move entire slur to the right
                                      by the amount (byte3 - 128)
                     if byte3 < 128,  move entire slur to the left
                                      by the amount (128 - byte3)
                     if byte3 = 0,    do nothing

          byte4:   modification of vertical position of slur (from default)

                     if byte4 >= 128, move entire slur down by the
                                      amount (byte4 - 128)
                     if byte4 < 128,  move entire slur up by the
                                      amount (128 - byte4)
                     if byte4 = 0,    do nothing

      For codes 24-27 = ending slurs ")]}x" the data stored
      in each byte is as follows:

          byte1:   modification of horizontal end of slur (from default)

                     if byte1 >= 128, move end of slur to the right
                                      by the amount (byte1 - 128)
                     if byte1 < 128,  move end of slur to the left
                                      by the amount (128 - byte1)
                     if byte1 = 0,    do nothing

          byte2:   modification of vertical end of slur (from default)

                     if byte2 >= 128, move end of slur down by the
                                      amount (byte2 - 128)
                     if byte2 < 128,  move end of slur up by the
                                      amount (128 - byte2)
                     if byte2 = 0,    do nothing

          byte3:   modification to curvature (normal range -1 to +5)
 
                     if byte1 >= 128, increase stock slur number by
                                      amount (byte1 - 128).  Up to a
                                      point, this will add to the curvature
                     if byte1 < 128,  decrease stock slur number by
                                      amount (128 - byte2).  This may have
                                      the effect of flattening the slur slightly
                     if byte1 = 0,    do nothing to length


      Beams in the Note Field 26       /* New 05/14/03
      ──────────────────────────

          code = 28

          byte2:   modification of first stem length (from default, as calculated
                     by mskpage or mkpart)

                     if byte2 >= 128, lengthen stem by the amount (byte2 - 128)
                                      (tenths of interline distance)
                     if byte2 < 128,  shorten stem by the amount (byte2 - 128)
                                      (tenths of interline distance)
                     if byte2 = 0     do nothing







    Vertical Parameters for guessing beam positions
    ───────────────────────────────────────────────

    bvpar(16) =  height parameter for beams
    bvpar(17) =  decrease in bvpar(16) when range of notes exceeds vpar(3)
    bvpar(18) =  cutoff of wevere up-down pattern under beam
    bvpar(20) =  amount to add to beam height to get stradle
    bvpar(22) =  fudge factor for two/more slanted beams on staff lines
    bvpar(23) =  fudge factor for one slanted beam on staff lines
    bvpar(24) =  maximum rise allowed for beam on one staff line
    bvpar(25) =  minimum rise allowed for beam crossing two staff lines
    bvpar(26) =  minimum rise allowed for beam crossing three staff lines
    bvpar(29) =  minimum stem length that triggers adding to 16th stem
    bvpar(30) =  adjustment for raising 16th beams because of short stems
    bvpar(31) = beam thickness
    bvpar(32) = offset between beams (if two or three)
    bvpar(33) = offset between beams (if more than three in staff line)
    bvpar(34) = amount by which a hanging beam exceeds line height
    bvpar(35) = maximum beam slope for short beams




            Explanation of Variables for NEWFONTS   03/19/04
        ───────────────────────────────────────────
     nsizes(12)      = The 12 available note sizes.  Currently four sizes are available
                         3 [06], 8 [14], 10 [18], and 11 [21]   (as of 12/18/04)
     revsizes(24)    = The reverse map to nsizes
     XFonts(12,19)   = The number of 10s and the 6 x 3 (sizes, styles) for each notesize
     XFontstr.76(12) = XFont data in string form
     Fspacex(90)     = index from (TMS font number - 50) to record in fontspac(.)
     kernmap(52,26)  = kerning data for current font
     kernfiles.360   = names of kern files





   Variables added 03-20-03 for additional code required by autoscr
   ────────────────────────────────────────────────────────────────

   Description of measuremap(MAX_MEAS,5)
 
      For each measure, we need to know how many tracks are active,
      and in the case of the grand staff, which staff should be
      considered the primary staff in that measure.
 
         Parameter 1 =  number of tracks active in this measure
 
      For each measure, we also need to know of any "time gaps"
      for any of the active tracks in the measure.
 
         Parameter 2 =  number of time gaps in measure
         Parameter 3 =  zero, if no time gaps
                     =  pointer to timegap data if present
 
      For each measure, we also need to know the number of divisions
      in the measure, and the number of divisions per quarter.
 
         Parameter 4 =  number of divisions in the measure
         Parameter 5 =  number of divisions per quarter
 

   Description of trackstave(MAX_MEAS,9,3)
 
      Trackstave data consists of three numbers for each of 9 possible tracks
 
         Parameter 1 =  relative time spent on staff 1
         Parameter 2 =  relative time spent on staff 2
         Parameter 3 =  primary staff for this track in this measure
 
   Description of timegaps(15000,3)
 
      Timegaps data consists of groups of three numbers.
 
         Parameter 1 =  track number
         Parameter 2 =  start of time for this timegap
         Parameter 3 =  length of time gap
 
   Description of pointers
 
         barnum   = pointer into measuremap(.,.) and trackstave(.,.,.)
         barnum2  = second counter of measure bars
         opbarnum = operative barnum at typesetting stage (changed when new bar is typeset)
         tgpnt    = pointer into timegaps(.,.)

   Description of other variables

         staves           = number of staves for this file (1 or 2)
         track            = current track number
         staff            = current staff number
         durflag          = flag that a duration has occurred in a measure
         trackdivpnt(9)   = division pointer for up to nine simultaneous tracks

         jscrdat          = line of SCORE data appended to end of object records
         kscrdat          = line of SCORE data appended to end of sub-object records
         scr_qwidth       = width of a SCORE quarter note is 9/10 MUSEDATA quarter

         how_much_mrest(2) = the divspq and divspm for a section of mrest.
                                  this is needed to construct the P7 parameter
                                  for multiple rests.

         str header1.80   = first header record
         str header2.80   = second header record
         str header3.80   = third header record
         str composer     = composer name
         str comp_names(.)= list of supported composers

   (int) composer_num     = composer number  1 = J.S.Bach
                                             2 = G.F.Handel
                                             3 = J. Haydn
                                             4 = L. Beethoven
         track_flag       = indicates presence of track assignments in stage2 file
         track_assign(9)  = automatic assignment of tracks to staves





   initialization of these parameters
   ══════════════════════════════════




       New code 03/19/04

      revsizes(1)  = 1
      revsizes(2)  = 1
      revsizes(3)  = 1
      revsizes(4)  = 1
      revsizes(5)  = 2
      revsizes(6)  = 3
      revsizes(7)  = 4
      revsizes(8)  = 5
      revsizes(9)  = 6
      revsizes(10) = 6
      revsizes(11) = 7
      revsizes(12) = 7
      revsizes(13) = 8
      revsizes(14) = 8
      revsizes(15) = 9
      revsizes(16) = 9
      revsizes(17) = 10
      revsizes(18) = 10
      revsizes(19) = 10
      revsizes(20) = 11
      revsizes(21) = 11
      revsizes(22) = 11
      revsizes(23) = 12
      revsizes(24) = 12

           start with notesize, and a number 30 to 48  (19 possibilities)
           want a font number, that's all

      XFontstr(1)  = "  51  51  81 111  51  81 111  52  82 112  53  83 113  54  84 114  56  86 116"
      XFontstr(2)  = "  51  52  82 112  53  83 113  54  84 114  55  85 115  56  86 116  58  88 118"
      XFontstr(3)  = "  51  54  84 114  55  85 115  56  86 116  57  87 117  58  88 118  60  90 120"
      XFontstr(4)  = "  52  55  85 115  57  87 117  58  88 118  59  89 119  60  90 120  63  93 123"
      XFontstr(5)  = "  53  57  87 117  58  88 118  59  89 119  61  91 121  62  92 122  64  94 124"
      XFontstr(6)  = "  55  59  89 119  61  91 121  63  93 123  64  94 124  65  95 125  68  98 128"
      XFontstr(7)  = "  57  62  92 122  64  94 124  65  95 125  67  97 127  69  99 129  72 102 132"
      XFontstr(8)  = "  58  64  94 124  66  96 126  68  98 128  70 100 130  72 102 132  74 104 134"
      XFontstr(9)  = "  60  67  97 127  69  99 129  71 101 131  73 103 133  74 104 134  76 106 136"
      XFontstr(10) = "  61  69  99 129  71 101 131  73 103 133  74 104 134  75 105 135  78 108 138"
      XFontstr(11) = "  64  72 102 132  74 104 134  75 105 135  77 107 137  78 108 138  79 109 139"
      XFontstr(12) = "  65  74 104 134  75 105 135  77 107 137  78 108 138  79 109 139  80 110 140"

      loop for i = 1 to 12
        sub = 1
        loop for j = 1 to 19
          XFonts(i,j) = int(XFontstr(i){sub..})
        repeat
      repeat

      loop for a1 = 1 to 30
        Fspacex(a1) = (a1 - 1) * 10 + 1
        Fspacex(a1+30) = Fspacex(a1) + 400
        Fspacex(a1+60) = Fspacex(a1) + 800
      repeat

      kernfiles = "S024S027S031S034S037S041S044S048S054S058S061S065S068S075S082"
      kernfiles = kernfiles // "S085S088S095S098S105S109S115S119S132S146S153S160S173S203S231"
      kernfiles = kernfiles // "B025B028B032B035B039B042B046B049B053B056B060B064B067B074B081"
      kernfiles = kernfiles // "B085B088B095B099B106B109B116B120B134B145B152B159B173B205B229"
      kernfiles = kernfiles // "I024I027I031I034I037I041I044I048I054I058I061I065I068I075I082"
      kernfiles = kernfiles // "I085I088I095I098I105I109I115I119I132I146I153I160I173I203I231"
      kernfiles = lcs(kernfiles)


    End of 03/19/04 material
 


      version = VERSION

#if AUTOSCR

      ligit_flag = 0

      comp_names(1) = "J.S.Bach"
      comp_names(2) = "G.F.Handel"
      comp_names(3) = "J. Haydn"
      comp_names(4) = "L. Beethoven"
      loop for i = 1 to 9
        track_assign(i) = 0
      repeat

      putc
      putc           ╔═════════════════════════════════════════╗
      putc           ║  MUSEDATA to SCORE conversion process   ║
      putc           ║  ====================================   ║
      putc           ╚═════════════════════════════════════════╝
      putc
      putc Part I: Building non page specific I-files from stage2 files
      putc
      putc     The home directory for this window should be directory
      putc     of the musical work you are converting.   The directory
      putc     should contain the sub-directories STAGE2 and OUTPUTS.
      putc
      putc   ════════════════════════════════════════════════════════════
      putc
      putc You are about to create a (set of) SCORECON I-file(s).  This program
      putc is in development and may incur changes.  For revision control purposes,
      putc please enter the current date (xx/xx/xx will work).  You may also enter
      putc your name or initials, if you choose.
      putc Example: 04/01/03 by W Hewlett
      getc line
      putc
      header1 = "SCORECON I-FILE.  created: " // line
      putc Composers currently supported by this program
      putc   1 = J.S.Bach
      putc   2 = G.F Handel
      putc   3 = J. Haydn
      putc   4 = L. Beethoven
      putc
      putc Please indicate the composer by entering the appropriate number.  If the
      putc   composer is not on the list, simply type Enter.
      getc composer_num
      if composer_num = 0 or composer_num > 4
        putc Note: Header records for this conversion may not be constructed in a
        putc       standardized manner.  Please let Eleanor know that your are
        putc       doing this conversion, so that we can add the name to our list.
        putc Enter the composer's name now.
        getc composer
      else
        composer = comp_names(composer_num)
      end

#else

      ligit_flag = LIGIT

      putc Musical Database Typesetting Program
      putc

#endif

Q1:
      notesize = 14
      mtfont = 31
      tword_height = 6
      twfont = 34
      abflg = 2
      cfactor = 100
      sizenum = revsizes(notesize)

#if AUTOSCR
#else

      putc Enter note size (<return> = 14: x = non standard parameters)
      getc line
      line = trm(line)
      if line <> ""
        if line = "x"
          putc Notesize?
          getc notesize
          putc Text font? (usually 31)
          getc mtfont
          putc Time word font? (usually 34)
          getc twfont
          putc Number of beats in alle breve time? (usually 2)
          getc abflg
          if abflg <> 4
            abflg = 2
          end
        else
          notesize = int(line)
          if chr(notesize) not_in [6,14,16,18,21]      /* Code modified 12/31/08
            putc Note size of ~notesize  is not supported at this time.
            putc Supported sizes are 6, 14, 16, 18, and 21
            putc
            goto Q1
          end
        end
      end
      sizenum = revsizes(notesize)          /* New 03/19/04

      putc Compression factor (<return> = none)
      getc line
      line = trm(line)
      if line <> ""
        cfactor = int(line)
        if cfactor = 0
          cfactor = 100
        end
      end

#endif

      bvpar(16) = 3 * notesize
      bvpar(17) = notesize / 2
      bvpar(18) = 30 * notesize / 16
      bvpar(20) = notesize / 2 + 1 / 2
      bvpar(22) = 6 * notesize / 16
      bvpar(23) = 9 * notesize / 16
      bvpar(24) = 7 * notesize / 16
      bvpar(25) = 22 * notesize / 16
      bvpar(26) = 27 * notesize / 16
      bvpar(29) = 38 * notesize / 16
      bvpar(30) = 3 * notesize - 8 / 16
      bvpar(31) = notesize / 2 + 1
      bvpar(32) = notesize * 8 + 4 / 10
      bvpar(33) = notesize * 12 + 10 / 14
      bvpar(34) = notesize - 3 / 9
      bvpar(35) = notesize / 3

      curfont = 0


   initialization
   ══════════════

     Vertical and horizontal parameters
     ──────────────────────────────────

      file = DISP_DISK // ":/release/progs/proofpar/" // chs(notesize)
      open [1,1] file
      loop for i = 1 to 200
        getf [1] vpar(i)
      repeat
      loop for i = 1 to 200
        getf [1] hpar(i)
      repeat
      vpar20 = 2 * vpar(10)
      scr_qwidth = hpar(82) * 9 / 10

#if BIG16
      if notesize = 16
        ++hpar(51)              /* width of quarter note (approximately)
        ++hpar(82)              /* width of black note (for typesetting)
        ++hpar(83)              /* width of whole note (for typesetting)
        ++hpar(84)              /* width of breve note (for typesetting)
      end
#endif

#if CUSTOM_PAR
      if notesize = 14
        vpar(101) = 111
      end
      if notesize = 16
        vpar(101) = 126
      end
      if notesize = 18            /* size-18 added 12/18/04
        vpar(101) = 141
      end
      if notesize = 21
        vpar(101) = 171
      end
#endif


     Other parameters and variables
     ──────────────────────────────

      loop for i = 1 to 9
        getf [1] wak(i)
      repeat
      loop for i = 1 to 2
        loop for j = 1 to 6
          getf [1] zak(i,j)
        repeat
      repeat
      close [1]

      claves = "CDEFGAB"
      numbers = "0123456789"
      accs = " #f"
      slurstr = "FpmFjoiOlpmFooiOphpFokoiffnFggnHFfFFIgGJcceBdddQBaAPEdQQcbeedddM"
      slurstr = slurstr // "KaNKddNMBaAAECCDlpmFIGGOlpmFOGOOphpFoiGHffnFggNH"
      slurstr = slurstr // "FfFFIgGJcceBECQQcdeAECQQcbeeddLMKaNKMdNMAaAAECCD"
      slurunder = "FHHFIGOOFHHFIGOOFNFFINGGFFNFIGNHFFFFIGGJBBBBECCQ"
      slurunder = slurunder // "BBBBECCQKCKKQNLMKKNKMLNMBKAAECCD"
      slurover  = "lpppjoiolpppjoiophppokoiffnrggngffsngggncceedddd"
      slurover  = slurover  // "cceeddddcbeeddddcanaddndcaendddn"

    Meaning of curvedata:  Curvedata is meant to describe the
    approximate shape of slurs for various situations.  The slurs
    begin described are (flat) tips down.  The end points are
    assumed to be 0 and are therefore not included.  A slur between
    two notes need not be described, so that the first relevant
    description is a slur between three notes.

    The first dimension of curvedata contains the number of notes
    under the slur (not counting the end points).  The second
    dimension contains a number representing the curvature of the
    slur (from 1 to 4).  The third dimension contains the specific
    note number for the height data.  This number will range from
    1 to the number of notes under the slur (not counting the end
    points).




    Curvedata for notesize = 14

      curvedata(1,1,1) = 10
      curvedata(1,2,1) = 14
      curvedata(1,3,1) = 18
      curvedata(1,4,1) = 22

      curvedata(2,1,1) =  8
      curvedata(2,2,1) = 12
      curvedata(2,3,1) = 16
      curvedata(2,4,1) = 20

      curvedata(3,1,1) = 10     /*    8
      curvedata(3,1,2) = 12     /*   12
      curvedata(3,2,1) = 12     /*   10
      curvedata(3,2,2) = 16     /*   16
      curvedata(3,3,1) = 14     /*   12
      curvedata(3,3,2) = 20     /*   20
      curvedata(3,4,1) = 17     /*   15
      curvedata(3,4,2) = 24     /*   24

      curvedata(4,1,1) =  9     /*    7
      curvedata(4,1,2) = 12     /*   12
      curvedata(4,2,1) = 11     /*   10
      curvedata(4,2,2) = 16     /*   16
      curvedata(4,3,1) = 13     /*   12
      curvedata(4,3,2) = 20     /*   20
      curvedata(4,4,1) = 16     /*   15
      curvedata(4,4,2) = 24     /*   24

      curvedata(5,1,1) =  8     /*    6
      curvedata(5,1,2) = 13     /*   12
      curvedata(5,1,3) = 14     /*   13
      curvedata(5,2,1) = 11     /*    9
      curvedata(5,2,2) = 16     /*   15
      curvedata(5,2,3) = 18     /*   17
      curvedata(5,3,1) = 13     /*   11
      curvedata(5,3,2) = 19     /*   19
      curvedata(5,3,3) = 21     /*   21
      curvedata(5,4,1) = 16     /*   14
      curvedata(5,4,2) = 24     /*   23
      curvedata(5,4,3) = 25     /*   25

      curvedata(6,1,1) =  8     /*    5
      curvedata(6,1,2) = 12     /*   11
      curvedata(6,1,3) = 14     /*   13
      curvedata(6,2,1) = 11     /*    9
      curvedata(6,2,2) = 16     /*   15
      curvedata(6,2,3) = 18     /*   17
      curvedata(6,3,1) = 13     /*   11
      curvedata(6,3,2) = 20     /*   19
      curvedata(6,3,3) = 22     /*   21
      curvedata(6,4,1) = 16     /*   14
      curvedata(6,4,2) = 24     /*   23
      curvedata(6,4,3) = 25     /*   25

      curvedata(7,1,1) =  7     /*    5
      curvedata(7,1,2) = 11     /*   11
      curvedata(7,1,3) = 14     /*   13
      curvedata(7,1,4) = 15     /*   14
      curvedata(7,2,1) = 11     /*    9
      curvedata(7,2,2) = 16     /*   15
      curvedata(7,2,3) = 18     /*   17
      curvedata(7,2,4) = 19     /*   18
      curvedata(7,3,1) = 14     /*   11
      curvedata(7,3,2) = 20     /*   19
      curvedata(7,3,3) = 22     /*   21
      curvedata(7,3,4) = 23     /*   22
      curvedata(7,4,1) = 16     /*   14
      curvedata(7,4,2) = 24     /*   23
      curvedata(7,4,3) = 26     /*   25
      curvedata(7,4,4) = 27     /*   26

      curvedata(8,1,1) =  7     /*    5
      curvedata(8,1,2) = 11     /*   11
      curvedata(8,1,3) = 14     /*   13
      curvedata(8,1,4) = 15     /*   14
      curvedata(8,2,1) = 11     /*    9
      curvedata(8,2,2) = 16     /*   15
      curvedata(8,2,3) = 18     /*   17
      curvedata(8,2,4) = 19     /*   18
      curvedata(8,3,1) = 14     /*   11
      curvedata(8,3,2) = 20     /*   19
      curvedata(8,3,3) = 22     /*   21
      curvedata(8,3,4) = 23     /*   22
      curvedata(8,4,1) = 16     /*   14
      curvedata(8,4,2) = 24     /*   23
      curvedata(8,4,3) = 26     /*   25
      curvedata(8,4,4) = 27     /*   26

      loop for c1 = 2 to 8
        loop for c2 = 1 to 4
          c4 = c1 + 1 / 2 + 1
          c5 = 1
          loop for c3 = c1 to c4 step -1
            curvedata(c1,c2,c3) = curvedata(c1,c2,c5)
            ++c5
          repeat
        repeat
      repeat

    Scale for notesize = 6

      if notesize = 6
        loop for c1 = 1 to 8
          loop for c2 = 1 to 4
            loop for c3 = 1 to 8
              curvedata(c1,c2,c3) = curvedata(c1,c2,c3) * 3 + 3 / 7
            repeat
          repeat
        repeat
      end

    Scale for notesize = 21

      if notesize = 21
        loop for c1 = 1 to 8
          loop for c2 = 1 to 4
            loop for c3 = 1 to 8
              curvedata(c1,c2,c3) = curvedata(c1,c2,c3) * 21 + 7 / 14
            repeat
          repeat
        repeat
      end

    Scale for notesize = 18        12/18/04

      if notesize = 18
        loop for c1 = 1 to 8
          loop for c2 = 1 to 4
            loop for c3 = 1 to 8
              curvedata(c1,c2,c3) = curvedata(c1,c2,c3) * 18 + 7 / 14
            repeat
          repeat
        repeat
      end

    Scale for notesize = 16        12/31/08

      if notesize = 16
        loop for c1 = 1 to 8
          loop for c2 = 1 to 4
            loop for c3 = 1 to 8
              curvedata(c1,c2,c3) = curvedata(c1,c2,c3) * 16 + 7 / 14
            repeat
          repeat
        repeat
      end

*   End of Initialization of parameters

*   Determine operating mode

      debug_point = 10000
      pmode = 0
&D    putc Debug above measure number ? (return = no debug)
&D    getc line
&D    line = trm(line)
&D    if line <> ""
&D      pmode = 4
&D      debug_point = int(line)
&D    end

#if AUTOSCR

      putc
      putc Autoscr performs the first step of the MUSEDATA to SCORE conversion process.
      putc Autoscr takes stage2 source files as input and produces non-page
      putc specific intermediate files.  In this conversion process, the only
      putc files needed are the files with scrcon membership.
      putc
      putc Source library?  (e.b46 g.b46 , stage2/01)
      getc inlib
      inlib = trm(inlib)
      inlib = inlib // "/"
      getdir line
      inlib = line // "/" // inlib

      pgroup = PGROUP
      job_type = "s"

      putc
      putc Autoscr works on only one movement at a time.  The output library
      putc (for i-files) must already be allocated.  Autoscr will name the
      putc output files (i-files) according to the order of the input files
      putc in the group; i.b46 e. part 1 from the input group becomes the i-file "01".
      putc Autoset can work on a range of parts within a group.  You will be asked
      putc to provide this range.  Enter the output library and range now.
      putc
      putc Output library? (Enter a blank line to get default output library)
      getc outlib
      outlib = trm(outlib)
      if outlib = ""
        j = len(inlib) - 1
        temp = ""
        loop for i = j to 1 step -1
          if inlib{i} <> "/"
            temp = inlib{i} // temp
          else
            i = 0
          end
        repeat

        outlib = "outputs"
        line = "scrcon"
        perform check_for_lib (outlib,line)
        outlib = outlib // "/scrcon"
        line = "i-files"
        perform check_for_lib (outlib,line)
        outlib = outlib // "/i-files"
        line = temp
        perform check_for_lib (outlib,line)
        outlib = outlib // "/" // temp
      end

#else

      putc
      putc Autoset performs the first step of the music typesetting process.
      putc Autoset takes stage2 source files as input and produces non-page
      putc specific intermediate files.  Since the stage2 directory contains
      putc source files for a variety of uses, you need to specify the group
      putc (i.b46 e. sound, score, skore, parts, short or data) that you want
      putc autoset to work on.  Enter the source library and group name now.
      putc
      putc Source library?
      getc inlib
      inlib = trm(inlib)
      inlib = inlib // "/"
      getdir line
      inlib = line // "/" // inlib
      putc Group name? (default = data)
      getc line
      line = trm(line)
      line = lcs(line)
      line = mrt(line)
      if "sound^short^parts^score^skore^data" con line    /* 03/10/09 adding skore
        pgroup = line
      else
        putc This is an unconventional group name.  Would you please
        putc verify it by typing it again (or enter a conventional name).
        getc temp2
        temp2 = trm(temp2)
        temp2 = mrt(temp2)
        temp2 = lcs(temp2)
        if "sound^short^parts^score^skore^data^" con temp2   /* 03/10/09 adding skore
          pgroup = temp2
        else
          if temp2 = line
            pgroup = line
          else
            pgroup = "data"
            putc group name has been set to "data"
          end
        end
      end

    Set job_type for selective print suggestions

      if "sound^short^parts^score^skore^data^" con pgroup
        i = mpt / 6 + 1
        job_type = ".tpskd"{i}     /* 03/10/09 Expanding job_type to include
      end                          /*          k = skore (conductor's score)

      if job_type = "p"            /* setting multirest_flag  03/04/06
        multirest_flag = 1
      else
        multirest_flag = 0
      end

      putc
      putc Autoset works on only one movement at a time.  The output library
      putc (for i-files) must already be allocated.  Autoset will name the
      putc output files (i-files) according to the order of the input files
      putc in the group; i.b46 e. part 1 from the input group becomes the i-file "01".
      putc Autoset can work on a range of parts within a group.  You will be asked
      putc to provide this range.  Enter the output library and range now.
      putc
      putc Output library? (Enter a blank line to get default output library)
      getc outlib
      outlib = trm(outlib)
      if outlib = ""
        j = len(inlib) - 1
        temp = ""
        loop for i = j to 1 step -1
          if inlib{i} <> "/"
            temp = inlib{i} // temp
          else
            i = 0
          end
        repeat
        outlib = "outputs/" // pgroup
        if notesize <> 14
          if notesize < 10
            outlib = outlib // "0"
          end
          outlib = outlib // chs(notesize)
        end
        line = "i-files"
        perform check_for_lib (outlib,line)

        outlib = outlib // "/i-files"
        if temp <> "stage2"
          outlib = outlib // "/" // temp
        end
      end

#endif

      outlib = outlib // "/"
      getdir line
      outlib = line // "/" // outlib

   Check that outlib exists

      line2 = rev(outlib)
      line2 = line2{2..}

      if line2 con "/"
        line = line2{mpt+1..}
        line = rev(line)
        temp = rev(line2{1,mpt-1})

        perform check_for_lib (line,temp)
        goto ALLOCATED
      end

      putc This is bullshit
      stop

ALLOCATED:

      f1 = 10000

    Get names of input files

      open [9,1] inlib
      loop
        getf [9] line
        line = line{33..}
        line = trm(line)
        temp = inlib // "/" // line
        temp = inlib // line
        open [2,1] temp
        loop for i = 1 to 11
          getf [2] line2
        repeat
        line2 = line2 // " "
        temp4 = " " // pgroup // " "
        if line2 con temp4
          loop for i = 1 to 8
            getf [2] line2
            k = len(pgroup)
            if line2{1,k} = pgroup
              if line2 con "part "
                j = int(line2{sub+5..})
                if f1 = 10000
                  k = 0
                  if line2 con " of "
                    k = int(line2{sub+3..})
                  end
                  putc
                  putc There appear to be ~k  parts in this group.  Enter the first and
                  putc last numbers of the range you wish, or simply type <Enter> to
                  putc process all of them.
                  f1 = 0
                  getc f1 f2
                  if f1 = 0
                    f1 = 1
                    f2 = k
                  end
                  f3 = f1
                end
                if j >= f1 and j <= f2
                  infiles(j) = line
                end
              end
              i = 100
            end
          repeat
          if i <> 100
            putc file ~line  has a bad group membership format
            putc Please fix this problem before proceeding further.
            putc
            stop
          end
        end
        close [2]
      repeat
eof9:
      loop for i = f1 to f2
        if infiles(i) = ""
          putc Unable to find an input file for track ~i .  Please check
          putc to see that your tracks are within the range of the size of
          putc the group you are working with.
          putc
          stop
        end
      repeat

BIG:
      m_number = 0
      tuflag = 0
      loop for i = 1 to MAX_STAFF
        c8flag(i) = 0
        transflag(i) = 0
      repeat

      ctrflag = 0
      loop for i = 1 to MAX_PASS     /* ctrflag(.) is an array as of 12/08/07
        ctrflag(i) = 0
      repeat

      loop for i = 1 to 4
        loop for j = 1 to MAX_PASS
          loop for k = 1 to BM_SZ    /* New size parameter 05/14/03
            beampar(i,j,k) = 0
          repeat
        repeat
      repeat
      outslurs = "00000000"          /* clear all pending slur flags
      snum = 0
      esnum = 0
      loop for j = 1 to MAX_PASS
        tsnum(j) = 0
        pre_tsnum(j) = 0
        rest_flag(j) = 0
      repeat
      figdiv = 0
      cuediv = 0
      measnum = 0
      divpoint = 0
      sct = 0                 /* necessary so that ts(.,.) will be completely cleared
      maxsct = 0
      oldsct = 0
      supcnt = 0
      inctype = 0
      inctype_rem = 0
      vflag = 1
      mcat = 0
      granddist = vpar(66)
      global_tpflag = 0
      tpflag = 0
      xposi_shift = 0
      yposi_shift = 0
      textconflag = OFF
      restplace = 0
      fix_next_inctype = 0
      mdirfont = DEFAULT_MDIRFONT
      dtivfont = DEFAULT_DTIVFONT

        Code added 09/22/03 for more complete initialization of variables

      key = 0
      loop for i = 1 to 50
        claveax(i) = 0
        loop for j = 1 to 4          /* 06/04/08 was 3
          measax(j,i) = claveax(i)
        repeat
      repeat

      restoff = 0                    /* added 05/12/04
      text_flag = 0                  /* added 01/30/05
      text_loc = vpar(101)           /* added 01/30/05
      art_flag = 0                   /* added 05/26/05
      single_line = 0                /* added 12/18/05
      stem_change_flag = 0           /* added 12/20/05
      dot_difference_flag = 0        /* added 12/24/05
      irest_flag = 0                 /* added 01/01/06
      mreport_flag = 0               /* added 01/01/06
      debug_flag = 0                 /* added 01/01/06
      ending_height = vpar(40)       /* added 01/06/06
      key_reprint_flag = 0           /* added 11/26/06
      mixed_color_flag = 0           /* added 11/26/06
      suppress_key     = 0           /* added 11/02/07
      min_space = hpar(29)           /* added 11/19/07
      slur_adjust = 0                /* added 05/01/08
      in_line_edslur = 0             /* added 01/12/09
      large_clef_flag = 0            /* added 02/02/09
      rest_collapse = TRUE           /* added 03/15/09
      pitch_mod = 0                  /* added 11/27/09

#if AUTOSCR
      xdata_flag = 1
      scr_flag = 1
#else
      xdata_flag = 0
#endif

*********** Transfer file to Data Table ***********

      if f3 = 0
        putc Suspected problem with the allocation of group memberships
        putc in this directory.  Please check all relevent files before
        putc proceeding further.
        putc
        putc    Program Halted
        putc
        stop
      end
      instrument_number = f3
      transposition = 50

      file = inlib // infiles(f3)
      if f3 < 10
        outfile = outlib // "0" // chs(f3)
      else
        outfile = outlib // chs(f3)
      end
      putc
      putc Input file = ~file
      putc
      open [1,1] file
      loop for i = 1 to 10
        getf [1] line
        tput [X,i] ~line
      repeat

    Skip group membership information

      getf [1] line
      if line con ":"   /* looking for group memberships
        j = mpt + 1
        loop for k = 0 to 100
          out = txt(line,[' '],j)
        repeat while out <> ""
        loop for j = 1 to k   /*  k = number of group memberships
          getf [1] line
          line = line // pad(1)
          loop while line{1} = "&"
            loop
              getf [1] line
              line = line // pad(1)
            repeat while line{1} <> "&"
            getf [1] line
            line = line // pad(1)
          repeat
        repeat
      end

      box_flag = 0                          /* New 02/03/08
      track_flag = 0
      tracknum_flag = 0
      loop
        getf [1] line
        line = line // pad(6)
        loop while line{1} = "&"            /* skipping comments bracketed by & records
          loop
            getf [1] line
            line = line // pad(1)
          repeat while line{1} <> "&"
          getf [1] line
          line = line // pad(4)
        repeat
        if "Std" not_con line{1}          /* skipping Sound records, deleted records, and tags
          if line{1} = "@"
            if line con "SCORECON"                     /* keep only SCORECON type comments
              if scr_flag = 1
                ++i
                tput [X,i] ~line
                if line con "track assignment:"
                  track_flag = 1
                end
              end
            end
          else
            if line{1} = "a"                /* continuation records
              if len(line) > 15
                temp = line{16..}
                tget [X,i] line
                line = line // temp
                tput [X,i] ~line
              end
            else
              if line{1,2} = "Pv"                  /* New code 05/02/03
                if version{1,3} <> line{3,3}
                  putc
                  putc                      CAUTIONARY NOTICE
                  putc
                  putc The version of autoset you are running, version ~version ,
                  putc
                  putc does not correspond with the print suggestions, version ~line{3,4} ,
                  putc in this file.  There are two possible cases:
                  putc
                  putc Case I:  The version of autoset you are running is older (lower number)
                  putc          than the version number in the file.  Your version of autoset
                  putc          is probably still good, but you should upgrade your version of
                  putc          autoset at your earliest convenience.
                  putc
                  putc Case II: You are running a more recent version of autoset, and the file
                  putc          you are working on may be out of date.  We advise that you check
                  putc          carefully the output where print suggestions are applied to make
                  putc          sure the outcome is the desired one.  If everything checks out,
                  putc          you may avoid this notice in the future by simply updating the
                  putc          print suggestion version number (the Pv record) to correspond
                  putc          with the version of autoset you are running.  If the printed
                  putc          results to not look right, you will need to change (or possibly
                  putc          delete) the print suggestions in question.  If you cannot get
                  putc          your desired result by these changes, we suggest you consult the
                  putc          latest version of the stage2 source file documentation file.
                  putc
                  putc Type any key to continue
                  getk k
                else
                  if version{4} <> line{6}
                    putc NOTICE: Your version of autoset = ~version ; data version = ~line{3,4}
                    if version{4} < "1"
                      putc         The processing of I:2 multi-tracks has been changed.
                      putc         We suggest you check the output.
                      putc
                    end
                    if version{4} < "2"
                      putc         The data may contain rehearsal numbers/letters in boxes
                      putc         which your version will not process.
                      putc
                    end
                  end
                end

                            New 02/03/08

                if line{1,4} >= "4.02"
                  box_flag = 1
                end



              else

         New code 01/01/06 to implement certain run-time options for autoset

                if line{1,2} = "Px"
                  if line{3,3} con "m"
                    mreport_flag = 1
                  end
                  if line{3,3} con "s"
                    xdata_flag = 1
                  end
                  if line{3,3} con "d"
                    debug_flag = 1
                    putc Debug above measure number ? (return = no debug)
                    getc line
                    line = trm(line)
                    if line <> ""
                      debug_point = int(line)
                    end
                  end

                else
                  ++i
                  tput [X,i] ~line
                end
              end
            end
          end
        end
        if line{1} = "/"
          line = line // pad(5)
          if line{1,5} = "/FINE"
            loop
              getf [1] line
              line = line // pad(4)
            repeat while line{1,4} <> "/END"
          end
          if line{1,4} = "/END"
            ssize = i
            close [1]
            goto LOADED
          end
          goto eof1
        end
      repeat
eof1: putc Mis-use of "/" or File not properly terminated
      putc
      putc This error can also be caused by a missing comment
      putc terminator "&".
      putc
      stop

┌───────────────────────────────────────────────┐
│           Start Processing Data               │
└───────────────────────────────────────────────┘

LOADED:

      barnum = 0
      tgpnt  = 0

      if xdata_flag = 1
        perform survay_file
      end

      barnum2 = 1
      opbarnum = 1
      ttext = ""
      firstoff = 0
      sigflag = 0
      key = 0
      loop for i = 1 to 50
        claveax(i) = 0
      repeat
      repeater_flag = 0

      nstaves = 1
*
      tget [X,5] line
      line = trm(line) // " "
      if line con "MV#:"
        temp = trm(line{mpt+4..})
        line = line{1,mpt-1}
      end
      if line con "WK#:"
        line = trm(line{mpt+4..})
      end
      tget [X,6] sourcename
      tget [X,7] wname
      tget [X,8] mname
      tget [X,9] partname

#if AUTOSCR

      header2 = "Composer: " // composer // "     Source: " // sourcename
      if composer_num = 1
        header3 = "Work: BWV " // line // ":" // temp // "     " // wname // " / " // mname
      end
      if composer_num = 2
        header3 = "Work: " // line // ":" // temp // "     " // wname // " / " // mname
      end
      if composer_num = 3
        header3 = "Work: " // wname // " Mvmt: " // mname
      end
      if composer_num = 4
        header3 = "Work: " // wname // " Mvmt: " // mname
      end

#endif

      putc Work #: ~line     .t30 Work name: ~wname
      putc Movement: ~temp   .t30 Movement name: ~mname
      putc Part name: ~partname

      tget [X,10] out
      out = trm(out)
      a = 0
      loop for i = 1 to len(out)
        if "SATB" con out{i}
          a = text_loc                       /* New 01/30/05
          text_flag = 1                      /* New 01/30/05
          a = vpar(101)
        end
      repeat

      scnt = 11
      p = 0

      tput [Y,1] ~a
      tput [Y,2] J D 4 500 -120 1 6913 0 0
      tput [Y,3] W 0 0 44 ~mname
      outpnt = 3



    Special case code added 01/06/04.  Look for print suggestion tags
    placed at the beginning of the file.  This must be done here for
    the case of tag Y U 1.  The others follow along, but are not critical.

    Please note: This is NOT the top of the stage2 data processing loop.

      a10 = scnt
PRA:
      tget [X,a10] line
      ++a10
      line = line // pad(80)
      if line{1} = "P"
        if line{2} = " "
          sub = 2
          goto MORE_SUGG_A
        end
        if line con " "
          a4 = sub
          temp4 = line{2..sub}

       This notesize filter removes all P suggestions
         that do not meet notesize restrictions

          loop for i = 1 to len(temp4)
            if temp4{i} = "#"
              if temp4{i,2} = "#<"
                a1 = int(temp4{i+2..})      /* sets sub
                if notesize >= a1
                  goto PRA                  /* This suggestion does not apply
                end
                i = sub - 1                 /* prepare i for next code
              else
                if temp4{i,2} = "#>"
                  a1 = int(temp4{i+2..})    /* sets sub
                  if notesize <= a1
                    goto PRA                /* This suggestion does not apply
                  end
                  i = sub - 1               /* prepare i for next code
                else
                  a1 = int(temp4{i+1..})    /* sets sub
                  if notesize <> a1
                    goto PRA                /* This suggestion does not apply
                  end
                  i = sub - 1               /* prepare i for next code
                end
              end
            end
          repeat

          if temp4 con job_type
            sub = a4
            goto MORE_SUGG_A
          end
          if temp4 con "a"
            sub = a4
            goto MORE_SUGG_A
          end
        end
        goto PRA

MORE_SUGG_A:
        if line{sub..} con "C"
          ++sub
          d = int(line{sub..})         /* column number
          if line{sub} = ":"
            ++sub                        /* skip ":"
            g = sub
          else
            temp5 = ""
            loop while line{sub} <> ":" and sub < len(line)
              temp5 = temp5 // line{sub}
              ++sub
            repeat
            if line{sub} <> ":"
              putc Incomplete print suggestion
              putc line = ~line
              goto PRA
            end
            ++sub                        /* skip ":"
            g = sub
            temp5 = temp5 // " "

       This notesize filter removes all P suggestions
         that do not meet notesize restrictions

            loop for i = 1 to len(temp5)
              if temp5{i} = "#"
                if temp5{i,2} = "#<"
                  a1 = int(temp5{i+2..})      /* sets sub
                  if notesize >= a1
                    loop while line{g} <> " " and g < len(line)
                      ++g
                    repeat
                    sub = g                   /* skipping this suggestion
                    goto MORE_SUGG_A
                  end
                  i = sub - 1                 /* prepare i for next code
                else
                  if temp5{i,2} = "#>"
                    a1 = int(temp5{i+2..})    /* sets sub
                    if notesize <= a1
                      loop while line{g} <> " " and g < len(line)
                        ++g
                      repeat
                      sub = g                 /* skipping this suggestion
                      goto MORE_SUGG_A
                    end
                    i = sub - 1               /* prepare i for next code
                  else
                    a1 = int(temp5{i+1..})    /* sets sub
                    if notesize <> a1
                      loop while line{g} <> " " and g < len(line)
                        ++g
                      repeat
                      sub = g                 /* skipping this suggestion
                      goto MORE_SUGG_A
                    end
                    i = sub - 1               /* prepare i for next code
                  end
                end
              end
            repeat

            if temp5 con job_type or temp5 con "a"
              sub = g                  /* actually unnecessary
            else
              loop while line{g} <> " " and g < len(line)
                ++g
              repeat
              sub = g
              goto MORE_SUGG_A
            end
          end
          g = sub                      /* unnecessary


        Column 0: general suggestions

          if d = 0                     /* general suggestion
            temp = ""
            loop for a2 = g to len(line)
              temp = temp // line{g}
              ++g
            repeat while line{g} <> " "
            temp = temp // " "
            if temp con "y"
              a2 = mpt + 1
              if temp{a2} in ['0'..'9']
                a3 = int(temp{a2..})
                ++outpnt
                tput [Y,outpnt] Y U ~a3
              end
            end
            if temp con "z"
              a2 = mpt + 1
              a3 = int(temp{a2..})
              ++outpnt
              if a3 = 0
                tput [Y,outpnt] Y P 0
              else
                temp = temp{sub..}
                tput [Y,outpnt] Y P ~a3  ~temp
              end
            end
          else
            loop for a2 = g to len(line)
              ++g
            repeat while line{g} <> " "
          end
          sub = g
          goto MORE_SUGG_A
        end
        goto PRA
      end
      if line{1} = "$"
        goto PRA
      end

    End of special case code 01/06/04
 



    Set movement word (if present)

      out = mname
      partname = trm(partname)

     New code to implement // feature in partnames 12/21/05

      if partname con "//"
        temp3 = partname{mpt+2..}
        partname = partname{1,mpt-1} // pad(17)
        partname = partname // temp3
      end

      if partname <> ""
        out = out // ":  " // partname
      end
      if out <> ""
        oby = 0 - vpar(33) - notesize
        obx = p + hpar(39) + hpar(5)
        ++outpnt
        tput [Y,outpnt] J D 1 ~obx  ~oby  1 6913 0 0
        spn = 6913
        ++outpnt
        tput [Y,outpnt] W 0 -~vpar(8)  44 ~out
      end
      mrest = 0
      wrest = 0
      @n = 0
      old@n = 0
      xmindist = hpar(4) * cfactor                 /* New 12/16/03
      mindist  = xmindist / 100                    /* New 12/16/03
      mindist = hpar(4)
      minshort = 0
      goto PR


                                                                      
                  ┌───────────────────────────────┐                   
                  │    Process the data file      │                   
                  └───────────────────────────────┘                   
                                                                      


PR:
      tget [X,scnt] line
      ++scnt
      line = line // pad(80)
      if line{1} = "@"
#if AUTOSCR
        if line con "SCORECON"                   /* This section added 11/27/09
          if line con "pitch transposition:"
            pitch_mod = int(line{mpt+20..})
          end
        end
#endif
        goto PR
      end
      d = int(line{6,3})           /* possible duration
      g = int(line{9,4})           /* possible measure number
      if line{1} = "$"
        if mrest > 0               /* this code added 1-27-93
          perform setmrest
        end
        perform process_section
        goto PR
      end

#if NO_EDIT
      if " ABCDEFGgcri" con line{1}
        if line{32..43} con "&"
          temp = line{44..}
          line = line{1..sub-1} // pad(43)
          line = line // temp
        end
      end
#endif



      MAIN CODE FOR PRINT SUGGESTIONS  (ends around line 4800)
    ===================================


      if line{1} = "P"

    Re-coding this section 12/16/03 to add notesize select feature
      and to fix the problem of consecutive suggestion records
 
        sugg_flg = 0                               /* 05/02/03
        sugg_flg2 = 0                              /* 05/02/03

        a1 = 1
        loop while a1 < 10
          ++a1
          tget [X,scnt-a1] temp3
        repeat while temp3{1} = "P"

                                   /* This code added 02/23/97
        if line{2} = " "
          sub = 2
          goto MORE_SUGG
        end
        if line con " "
          a4 = sub
          temp4 = line{2..sub}

       This notesize filter removes all P suggestions
         that do not meet notesize restrictions

          loop for i = 1 to len(temp4)
            if temp4{i} = "#"
              if temp4{i,2} = "#<"
                a1 = int(temp4{i+2..})      /* sets sub
                if notesize >= a1
                  goto PR                   /* This suggestion does not apply
                end
                i = sub - 1                 /* prepare i for next code
              else
                if temp4{i,2} = "#>"
                  a1 = int(temp4{i+2..})    /* sets sub
                  if notesize <= a1
                    goto PR                 /* This suggestion does not apply
                  end
                  i = sub - 1               /* prepare i for next code
                else
                  a1 = int(temp4{i+1..})    /* sets sub
                  if notesize <> a1
                    goto PR                 /* This suggestion does not apply
                  end
                  i = sub - 1               /* prepare i for next code
                end
              end
            end
          repeat

          if temp4 con job_type
            sub = a4
            goto MORE_SUGG
          end
          if temp4 con "a"
            sub = a4
            goto MORE_SUGG
          end
        end
        goto PR                    /* end of 02/23/97 addition


        sugg_flg = 0                               /* 05/02/03
        sugg_flg2 = 0                              /* 05/02/03
        line = line // " "         /* This code added 02/23/97
        sub = 2
        if line{2} = " "
          tget [X,scnt-2] temp3
          goto MORE_SUGG
        end
        if line con " "
          a4 = mpt
          temp3 = line{2..sub}
          if temp3 con job_type
            tget [X,scnt-2] temp3
            goto MORE_SUGG
          end
        end
        goto PR                    /* end of 02/23/97 addition


MORE_SUGG:
        if line{sub..} con "C"
          ++sub
          d = int(line{sub..})         /* column number

      Code added 11/04/03 to allow for job-specific print suggestions to
      be specified by column number.

          if line{sub} = ":"
            ++sub                        /* skip ":"
            g = sub
          else
            temp5 = ""
            g = sub
            loop while line{sub} <> ":" and sub < len(line) and sub < g + 20
              temp5 = temp5 // line{sub}
              ++sub
            repeat
            if line{sub} <> ":"
              putc
              putc Incomplete print suggestion.  This fault should be fixed.
              putc index = ~(scnt+5)   line = ~line
              putc
              goto PR
            end
            ++sub                        /* skip ":"
            g = sub

    Re-coding this section 12/16/03 to add notesize select feature
 
            temp5 = temp5 // " "

       This notesize filter removes all P suggestions
         that do not meet notesize restrictions

            loop for i = 1 to len(temp5)
              if temp5{i} = "#"
                if temp5{i,2} = "#<"
                  a1 = int(temp5{i+2..})      /* sets sub
                  if notesize >= a1
                    loop while line{g} <> " " and g < len(line)
                      ++g
                    repeat
                    sub = g                   /* skipping this suggestion
                    goto MORE_SUGG
                  end
                  i = sub - 1                 /* prepare i for next code
                else
                  if temp5{i,2} = "#>"
                    a1 = int(temp5{i+2..})    /* sets sub
                    if notesize <= a1
                      loop while line{g} <> " " and g < len(line)
                        ++g
                      repeat
                      sub = g                 /* skipping this suggestion
                      goto MORE_SUGG
                    end
                    i = sub - 1               /* prepare i for next code
                  else
                    a1 = int(temp5{i+1..})    /* sets sub
                    if notesize <> a1
                      loop while line{g} <> " " and g < len(line)
                        ++g
                      repeat
                      sub = g                 /* skipping this suggestion
                      goto MORE_SUGG
                    end
                    i = sub - 1               /* prepare i for next code
                  end
                end
              end
            repeat

            if temp5 con job_type or temp5 con "a"
              sub = g                  /* actually unnecessary
            else
              loop while line{g} <> " " and g < len(line)
                ++g
              repeat
              sub = g
              goto MORE_SUGG
            end


            if temp5 con job_type
              sub = g
            else
              loop while line{g} <> " " and g < len(line)
                ++g
              repeat
              sub = g
              goto MORE_SUGG
            end

          end
          g = sub                      /* unnecessary


        Column 0: general suggestions

          if d = 0                     /* general suggestion
PQST:
            if "acdFfghjkmnpqrstvxyz" con line{g} /* "a" added 05/26/05, and PSUG nums advanced
                                                  /* "x" added (and string re-ordered) 01/03/04
                                                  /* "y" and "z" added 01/06/04
                                                  /* "c" added 05/12/04, and PSUG nums advanced
                                                  /* "v" added 01/30/05, and PSUG nums advanced
                                                  /* "j" added 12/20/05, and PSUG nums advanced
                                                  /* "k" added 12/24/05, and PSUG nums advanced
                                                  /* "m" added 03/04/06, and PSUG nums advanced
                                                  /* "F" added 10/24/07, and PSUG nums advanced
                                                  /* "h" added 11/19/07, and PSUG nums advanced
                                                  /* "g" added 05/01/08, and PSUG nums advanced
              goto PSUG(mpt)

PSUG(1):                                             /* line{g} = "a"  (New 05/26/05)
              art_flag = int(line{g+1..})
              g = sub
              goto PQST
PSUG(2):                                             /* line{g} = "c"  (New 05/12/04)
              restoff = int(line{g+1..})
              g = sub
              if restoff <> 0
                restoff = 1
              end
              goto PQST
PSUG(3):                                             /* line{g} = "d"  (Modified 01/06/06)
              a6 = int(line{g+1..})
              tword_height = a6
              ending_height = vpar(2) * a6 / 2       /* New 01/06/06
              g = sub
              goto PQST
PSUG(4):                                             /* line{g} = "F"
              dtivfont = int(line{g+1..})
              g = sub
              goto PQST
PSUG(5):                                             /* line{g} = "f"
              mdirfont = int(line{g+1..})
              g = sub
              goto PQST
PSUG(6):                                             /* line{g} = "g"  (New 05/01/08)
              slur_adjust = int(line{g+1..})
              g = sub
              goto PQST
PSUG(7):                                             /* line{g} = "h"  (New 11/19/07)
              a6 = int(line{g+1..})
              min_space = hpar(29) * a6 / 100
              g = sub
              goto PQST
PSUG(8):                                             /* line{g} = "j"  (New 12/20/05)
              stem_change_flag = int(line{g+1..})
              g = sub
              goto PQST
PSUG(9):                                             /* line{g} = "k"  (New 12/24/05)
              a6 = int(line{g+1..})
              dot_difference_flag = a6 & 0x01
              key_reprint_flag = a6 & 0x02           /* added 11/26/06
              mixed_color_flag = a6 & 0x04           /* added 11/26/06
              suppress_key     = a6 & 0x08           /* added 11/02/07
              in_line_edslur   = a6 & 0x10           /* added 01/12/09
              large_clef_flag  = a6 & 0x20           /* added 02/02/09
              g = sub
              goto PQST
PSUG(10):                                            /* line{g} = "m"  (New 03/04/06)
              a6 = int(line{g+1..})
              if a6 = 1
                multirest_flag = 1
              else
                multirest_flag = 0
              end
              g = sub
              goto PQST
PSUG(11):                                            /* line{g} = "n"
              m_number = int(line{g+1..})
              g = sub
              goto PQST
PSUG(12):                                            /* line{g} = "p"
              xmindist = int(line{g+1..}) * hpar(4) * cfactor / 100      /* New 12/16/03
              mindist  = xmindist / 100                                  /* New 12/16/03
              mindist = int(line{g+1..}) * hpar(4) / 100
              g = sub
              perform newnsp
              goto PQST
PSUG(13):                                            /* line{g} = "q"
              minshort = int(line{g+1..})
              g = sub
              perform newnsp
              goto PQST
PSUG(14):                                            /* line{g} = "r" (New treatment 03/15/09)
              a6 = int(line{g+1..})
              restplace = a6 & 0x01
              irest_flag = (a6 & 0x02) >> 1
              rest_collapse = (a6 & 0x04) >> 2       /* New 03/15/09: 0 = TRUE; 1 = FALSE
              g = sub
              goto PQST
PSUG(15):                                            /* line{g} = "s"
              granddist = int(line{g+1..})
              g = sub
              granddist = granddist * vpar(2) + 5 / 10
              goto PQST
PSUG(16):                                            /* line{g} = "t"
              global_tpflag = int(line{g+1..})
              g = sub
              if global_tpflag > 4
                global_tpflag = 4
              end
              if global_tpflag < 0
                global_tpflag = 0
              end
              tpflag = global_tpflag
              goto PQST

      This option added 01/30/05

PSUG(17):                                            /* line{g} = "v"
              a6 = int(line{g+1..})
              g = sub
              text_loc = a6 * notesize / 20
              tget [Y,1] temp4
              a6 = int(temp4)
              temp4 = temp4 // "  "
              temp4 = temp4{sub..}
              temp4 = mrt(temp4)
              tput [Y,1] ~text_loc  ~temp4
              goto PQST

      This option added 01/03/04; modified 01/06/04

PSUG(18):                                            /* line{g} = "x"
              a6 = int(line{g+1..})
              if a6 = 1 and mrest > 0
                perform setmrest
              end
              wrest = a6
              if wrest <> 1
                wrest = 0
              end
              g = sub
              goto PQST



      These options added 01/06/04

PSUG(19):                                            /* line{g} = "y"
              a6 = int(line{g+1..})
              ++outpnt
              tput [Y,outpnt] Y U ~a6
              g = sub
              goto PQST
PSUG(20):                                            /* line{g} = "z"
              a6 = int(line{g+1..})
              ++outpnt
              if a6 = 0
                tput [Y,outpnt] Y P 0
                g = sub
              else
                g = sub
                temp = ""
                loop while line{g} <> " " and g < 80
                  temp = temp // line{g}
                  ++g
                repeat
                if line{g} <> " "
                  dputc Program Error
                  stop
                end
                tput [Y,outpnt] Y P ~a6  ~temp
              end
              goto PQST

            end
            sub = g
            goto MORE_SUGG
          end

      Deal with record that contains: notes, grace notes, cue notes, rests, figures

          if " ABCDEFGgcrif" con temp3{1}    /* 04/24/03 allowing print sugg for chords
            a3 = mpt

        Column 1: The Object itself.  NOTES, GRACE NOTES, CUE NOTES, RESTS, FIGURES

            if d = 1
              if "spxXyY" con line{g}        /* "X" added 05/02/03   "s" added 02/19/06
                ++@n
                tcode(@n) = zpd(4)
                tcode(@n){1} = chr(1)
                tv1(@n) = P_SUGGESTION
                tv2(@n) = 0x0300
              end
ABCL:
              if line{g} = "p"
                i = int(line{g+1..})
                g = sub
                if i < 0
                  i = 0
                end
                if i > 7
                  i = 7
                end
                if i > 0
                  i = i << 1 + 1
                end
                tcode(@n){1} = chr(i)
                goto ABCL
              end

         This code added 02/19/06 to implement different shapes of note heads

              if line{g} = "s"
                i = int(line{g+1..})
                g = sub
                if i < 0
                  i = 0
                end
                if i > 15
                  i = 15
                end
                i <<= 4                           /* use upper part of first byte
                a3 = ors(tcode(@n){1})
                a3 |= i                           /* add to what is already there
                a3 |= 0x01                        /* turn on "active" bit
                tcode(@n){1} = chr(a3)
                goto ABCL
              end

         End of 02/19/06 addition

              if "xXyY" con line{g}                          /* 05/02/03 code revised
                a3 = mpt
                if line{g+1} = "+"
                  ++g
                end
                a2 = int(line{g+1..})
                g = sub
                a2 += 128
                if a2 <= 0
                  a2 = 1
                end
                if a2 > 255
                  a2 = 255
                end
                a4 = ors(tcode(@n){2})                       /* 05/02/03 code revised
                if a3 < 3
                  tcode(@n){3} = chr(a2)
                  if a3 = 1
                    a4 |= 0x01                               /* set position as "relative"
                  else
                    a4 |= 0x03                               /* set position as "absolute"
                  end
                else
                  tcode(@n){4} = chr(a2)
                  if a3 = 3
                    a4 |= 0x01                               /* set position as "relative"
                  else
                    a4 |= 0x05                               /* set position as "absolute"
                  end
                end
                tcode(@n){2} = chr(a4)
                goto ABCL
              end
              sub = g
              goto MORE_SUGG
            end

        Columns 18 and 19: dots and accidentals on NOTES, GRACE NOTES, CUE NOTES, and RESTS

            if (d = 18 or d = 19) and a3 < 12                /* 05/02/03
              i = d                           /* 18 = dots, 19 = accs
              if "xXyY" con line{g}
                a3 = mpt
                ++@n
                tcode(@n) = zpd(4)
                tv1(@n) = P_SUGGESTION
                tv2(@n) = 0x0200 + i               /* i is index into position string
NXYP2:
                if line{g+1} = "+"
                  ++g
                end
                a2 = int(line{g+1..})
                g = sub
                a2 += 128
                if a2 <= 0
                  a2 = 1
                end
                if a2 > 255
                  a2 = 255
                end
                a4 = ors(tcode(@n){2})
                if a3 < 3
                  tcode(@n){3} = chr(a2)
                  if a3 = 1
                    a4 |= 0x01                               /* set position as "relative"
                  else
                    a4 |= 0x03                               /* set position as "absolute"
                  end
                else
                  tcode(@n){4} = chr(a2)
                  if a3 = 3
                    a4 |= 0x01                               /* set position as "relative"
                  else
                    a4 |= 0x05                               /* set position as "absolute"
                  end
                end
                tcode(@n){2} = chr(a4)
                if "xXyY" con line{g}
                  a3 = mpt
                  goto NXYP2
                end
              end
              sub = g
              goto MORE_SUGG
            end

        Columns 26 to 30: beams
 
            if (d = 26 or d = 27) and a3 < 11
              if "baA" con line{g}
              if "baAc" con line{g}                  /* "c" option added 01/01/08
                repeater_flag = mpt - 1
                if d = 27 and repeater_flag > 0
                  repeater_flag += 4
                end
                sub = g
                goto MORE_SUGG
              end

              if d = 26                              /* New code 05/14/03
                i = 28                               /* 28 = beam stem length code
                if line{g} = "y"
                  ++@n
                  tcode(@n) = zpd(4)
                  tv1(@n) = P_SUGGESTION
                  tv2(@n) = 0x0200 + i               /* i is index into position string

                  ++g
                  sub = g
                  if line{sub} = "+"
                    ++sub
                  end
                  a2 = int(line{sub..})
                  g = sub
                  a2 += 128
                  if a2 < 1
                    a2 = 1
                  end
                  if a2 > 255
                    a2 = 255
                  end
                  tcode(@n){2} = chr(a2)
                end
              end

              sub = g
              goto MORE_SUGG
            end

        Columns 32 to 43: ties, articulations, ornaments, dynamics,
                            fermatas, technical suggestions (fingerings, etc.)

            if d >= 32 and d <= 43 and a3 < 12               /* 04/24/03 11 changed to 12

        Slur suggestions.  Additions and modifications to code on 05/06/03

              if "([{z" con temp3{d}                         /* start slur 1,2,3,4
                a5 = mpt
                if "ou" con line{g}    /* this is a forced slur suggestion
                  i = a5 - 1 << 1 - 1 + mpt
                  ++@n
                  tv1(@n) = P_SUGGESTION
                  tv2(@n) = i
                  sub = g
                  goto MORE_SUGG
                end
                i = a5 + 19            /* 20, 21, 22, 23

     New code 04/26/05 for print suggestion suppressing the printing of a slur

                if line{g} = "*"
                  ++@n
                  tcode(@n) = ch4(-1)                /* 0xffffffff = suppress slur
                  tv1(@n) = P_SUGGESTION
                  tv2(@n) = 0x0200 + i               /* i is index into position string
                  sub = g
                  goto MORE_SUGG
                end

                if "xyXY" con line{g}
                  a3 = mpt
                  ++@n
                  tcode(@n) = zpd(4)
                  tv1(@n) = P_SUGGESTION
                  tv2(@n) = 0x0200 + i               /* i is index into position string
NXYH:
                  ++g
                  sub = g
                  if line{sub} = "+"
                    ++sub
                  end
                  a2 = int(line{sub..})
                  g = sub
                  a2 += 128
                  if a2 < 1
                    a2 = 1
                  end
                  if a2 > 255
                    a2 = 255
                  end
                  tcode(@n){a3} = chr(a2)

                  if "xyXY" con line{g}
                    a3 = mpt
                    goto NXYH
                  end
                end
                sub = g
                goto MORE_SUGG
              end

        More slur suggestions

              if ")]}x" con temp3{d}                         /* end slur 1,2,3,4
                i = mpt + 23           /* 24, 25, 26, 27
                if "xyh" con line{g}
                  a3 = mpt
                  ++@n
                  tcode(@n) = zpd(4)
                  tv1(@n) = P_SUGGESTION
                  tv2(@n) = 0x0200 + i               /* i is index into position string
NXYH2:
                  ++g
                  sub = g
                  if line{sub} = "+"
                    ++sub
                  end
                  a2 = int(line{sub..})
                  g = sub
                  a2 += 128
                  if a2 < 1
                    a2 = 1
                  end
                  if a2 > 255
                    a2 = 255
                  end
                  tcode(@n){a3} = chr(a2)

                  if "xyh" con line{g}
                    a3 = mpt
                    goto NXYH2
                  end
                end
                sub = g
                goto MORE_SUGG
              end

        End of 05/06/03 Addition

              if temp3{d} = "-"
                if "ou" con line{g}    /* this is a specified tie
                  ++@n
                  tv1(@n) = P_SUGGESTION
                  tv2(@n) = mpt + 7
                end
              end
              if "_.=i>VArt~wMkvnoQ012345mpfZRFE-" con temp3{d}
              if "_.=i>VArt~wMkTvnoQ012345mpfZRFE-" con temp3{d}     /* Tremulo added 01/07/06
              if "_.=i>VArt~wMkTJKvnoQ012345mpfZRFE-" con temp3{d}   /* Back ties added 04/22/08
                i = mpt - 1 << 1 + 1

           Tremulo added to this map 01/07/06
 
           Back ties added to this map 04/22/08
                 i = int("01010102030303040404040404  060607080809090909091414141414151617"{i,2})
                                                     ↓ ↓
                i = int("0101010203030304040404040404    060607080809090909091414141414151617"{i,2})
                i = int("01010102030303040404040404040404060607080809090909091414141414151617"{i,2})


    Explanation: We need to have a code which indicates the type of element to which
                 the suggestions is applied.  So for, we have the following codes:

                 1 = legato, staccato, or legato-staccate articulation
                 2 = spiccato articulation
                 3 = horizontal, vertical, or inverted vertical accent
                 4 = turn, trill, wavy line, shake, mordant, or delayed turn ornament
                                                tremulo added 01/07/06
                                                back ties added 04/22/08
                 5 = (same thing, I think)
                 6 = up bow, or down bow bowing
                 7 = harmonic
                 8 = open string, or thumb position
              9-13 = fingering (five suggestions possible)
                14 = dynamics
                15 = upright fermata
                16 = inverted fermata
                17 = tie
                18 = dots
                19 = accidentals
            (20-23 = start slur)
            (24-27 = stop slur)

                if i = 4                             /* ornament
                  if sugg_flg2 < 2
                    ++sugg_flg2
                    i = sugg_flg2 + 3
                  end
                end
                if i = 9                             /* fingering
                  if d > 32 and temp3{d-1} = ":"
                    i = 1000                         /* i = 1000 means "do nothing"
                  else
                    if sugg_flg < 5
                      ++sugg_flg
                      i = sugg_flg + 8
                    end
                  end
                end
                if line{g} = "L" and i <> 17         /* 05/02/03 "L" applies only to ties
                  i = 1000
                end

                if i < 1000 and "xXyYabL" con line{g}   /* modifications to code 05/02/03
                  a3 = mpt
                  ++@n
                  tcode(@n) = zpd(4)
                  tv1(@n) = P_SUGGESTION
                  tv2(@n) = 0x0200 + i               /* i is index into position string
NXYP:
                  if a3 < 5
                    ++g
                    sub = g
                    if line{sub} = "+"
                      ++sub
                    end
                    a2 = int(line{sub..})
                    g = sub
                    a2 += 128
                    if a2 < 1
                      a2 = 1
                    end
                    if a2 > 255
                      a2 = 255
                    end
                    a4 = ors(tcode(@n){2})
                    if a3 < 3
                      tcode(@n){3} = chr(a2)
                      if a3 = 1
                        a4 |= 0x01                           /* set position as "relative"
                      else
                        a4 |= 0x03                           /* set position as "absolute"
                      end
                    else
                      tcode(@n){4} = chr(a2)
                      if a3 = 3
                        a4 |= 0x01                           /* set position as "relative"
                      else
                        a4 |= 0x05                           /* set position as "absolute"
                      end
                    end
                    tcode(@n){2} = chr(a4)
                    if i <> 17
                      a2 = ors(tcode(@n){1}) | 0x01          /* added 11/10/07   Major oversight, check results
                      tcode(@n){1} = chr(a2)
                    end
                  end

                  if a3 = 5 or a3 = 6
                    a4 = a3 - 5 * 4 + 3           /* 5 -> 3,  6 -> 7
                    a2 = ors(tcode(@n){1}) | a4
                    tcode(@n){1} = chr(a2)
                    ++g
                  end

                  if a3 = 7                          /* 05/02/03 "L" changes length of tie
                    ++g
                    sub = g
                    if line{sub} = "+"
                      ++sub
                    end
                    a2 = int(line{sub..})
                    g = sub
                    a2 += 128
                    if a2 < 1
                      a2 = 1
                    end
                    if a2 > 255
                      a2 = 255
                    end
                    tcode(@n){1} = chr(a2)
                  end

                  if "xXyYabL" con line{g}
                    a3 = mpt
                    if a3 < 7 or i = 17              /* 05/02/03 "L" applies only to ties
                      goto NXYP
                    end
                  end
                end
                sub = g
                goto MORE_SUGG
              end

         Suggestions for tuples

              if temp3{d} = "*"                /* 03-21-97
                if "[(:;i" con line{g}
                  a3 = mpt
                  ++@n
                  tv1(@n) = P_SUGGESTION
                  tv2(@n) = 0x10               /* tuplet suggestion
MOTUP:
                  if a3 = 2 or a3 = 4
                    tv2(@n) |= 0x01            /* round tuplet
                  end
                  if a3 = 1 or a3 = 2 or a3 = 5
                    tv2(@n) |= 0x02            /* continuous tuplet
                  end
                  if a3 = 3
                    tv2(@n) = 0x10             /* square, broken tuplet (default)
                  end
                  if a3 = 5
                    tv2(@n) |= 0x04            /* tuplet number inside bracket
                  end
                  if "[(:;i" con line{g+1}
                    ++g
                    a3 = mpt
                    goto MOTUP
                  end
                end
              end
              if temp3{d} = "!"                /* 11/05/05

          New code 11/05/05 implementing post adjustment to tuple position

MOTUP2:
                if line{g} = "x"
                  a2 = int(line{g+1..})
                  a2 *= vpar(2)
                  a2 /= 10
                  g = sub
                  if abs(a2) < 128
                    ++@n
                    tv1(@n) = P_SUGGESTION
                    tv2(@n) = 0x500            /* x adjustment to tuplet
                    a2 += 128
                    tv2(@n) += a2
                  end
                  goto MOTUP2
                end
                if line{g} = "y"
                  a2 = int(line{g+1..})
                  a2 *= vpar(2)
                  a2 /= 10
                  g = sub
                  if abs(a2) < 128
                    ++@n
                    tv1(@n) = P_SUGGESTION
                    tv2(@n) = 0x600            /* x adjustment to tuplet
                    a2 += 128
                    tv2(@n) += a2
                  end
                  goto MOTUP2
                end
              end
                       End of 11/05/05 addition

              sub = g
              goto MORE_SUGG
            end
          end

       Print suggestions applied to musical directions  (not modified as of 05/02/03)

          if temp3{1} = "*"
            if d >= 17 and d <= 18
              if "fxypY" con line{g}
                ++@n
                tcode(@n) = zpd(4)
                tv1(@n) = P_SUGGESTION
                if "ABCDGPQ" con temp3{d}
                if "ABCDGPQR" con temp3{d}       /* New 02/03/08
                  tv2(@n) = 0x0100
                else
                  tv2(@n) = 0x0101
                end
              end
NXFP:
              if line{g} = "f"
                i = int(line{g+1..})
                g = sub
                if "ABCDG" con temp3{d}  /* this is a designated font number
                if "ABCDGR" con temp3{d}  /* this is a designated font number  New 02/03/08
                  tcode(@n){1} = chr(i)
                end
                goto NXFP
              end

              if "xyYp" con line{g}
                a3 = mpt + 1
                if a3 = 5
                  a3 -= 2
                end
                if line{g+1} = "+"
                  ++g
                end
                i = int(line{g+1..})
                i += 0x80
                if i <= 0
                  i = 1
                end
                if i > 255
                  i = 255
                end
                g = sub
                if "ABCDEFGHPQUV" con temp3{d}   /* this is a position shift
                if "ABCDEFGHPQRUV" con temp3{d}  /* this is a position shift  New 02/03/08
                  tcode(@n){a3} = chr(i)
                end
                goto NXFP
              end
              sub = g
              goto MORE_SUGG
            end
            if d >= 25 and line{g} = "f" and temp3{17,2} con ['B'..'D']
            if d >= 25 and line{g} = "f" and temp3{17,2} con ['B'..'D','R']   /* New 02/03/08
              i = int(line{g+1..})
              g = sub
              temp3 = temp3 // pad(100)

          De-construct temp3 into ASCII and font changes

              loop for a1 = 1 to 10
                font_changes(a1,1) = 0
                font_changes(a1,2) = 0
              repeat
              changecnt = 0
              sub = 25
NXFNUM:
              if temp3{sub..} con "!" and temp3{sub+1} in ['0'..'9']
                a1 = sub
                a2 = int(temp3{a1+1..})
                ++changecnt
                font_changes(changecnt,1) = a1
                font_changes(changecnt,2) = a2

        Code change 01/17/04 to keep font changes from interferring with the text

                if temp3{sub} = "|"
                  ++sub
                end

                temp3 = temp3{1,a1-1} // temp3{sub..}
                sub = a1
                goto NXFNUM
              end

          Add new font change and re-order in ascending order of location

              ++changecnt
              font_changes(changecnt,1) = d
              font_changes(changecnt,2) = i
              loop for a1 = changecnt to 2 step -1
                a2 = a1 - 1
                if font_changes(a1,1) < font_changes(a2,1)
                  a3 = font_changes(a1,1)
                  font_changes(a1,1) = font_changes(a2,1)
                  font_changes(a2,1) = a3
                  a3 = font_changes(a1,2)
                  font_changes(a1,2) = font_changes(a2,2)
                  font_changes(a2,2) = a3
                end
              repeat

          Merge ASCII and font changes into new temp3

              temp4 = temp3{1,24}
              a2 = 25
              loop for a1 = 1 to changecnt
                a3 = font_changes(a1,1)
                if a3 > a2
                  temp4 = temp4 // temp3{a2..a3-1}
                end
                a2 = a3

        Code change 01/17/04 keep font changes from interferring with the text

                temp4 = temp4 // "!" // chs(font_changes(a1,2)) // "|"
                temp4 = temp4 // "!" // chs(font_changes(a1,2))

              repeat
              temp4 = temp4 // temp3{a2..}
              temp3 = temp4
              loop for a1 = @n to 1 step -1
                if tv1(a1) = MUSICAL_DIR
                  tdata(a1,1) = temp3{17..96}
                  a1 = 0
                end
              repeat
              sub = g
              goto MORE_SUGG
            end
          end

       Print suggestions applied to measures and barlines: New code 05/25/03

          if temp3{1} = "m"
            if d = 1


        New suggestion 10/24/08 to breakup a multi-rest measure (for parts)

              if line{g} = "f" and mrest > 0
                perform setmrest
              end



              if line{g} = "n"
                ++@n
                tcode(@n) = zpd(4)
                tv1(@n) = P_SUGGESTION
                tv2(@n) = 0x0400
              end

        New suggestion 05/28/05 to implement mid-movement right justification

        NOTE: This code contains a giant cludge.  If the print suggestion follows
              directly after a measure record, and "]" is the only suggestion, then
              this code reaches directly into the output and changes it.
 
              if line{g} = "]"
                if @n = 0
                  loop for i = outpnt to (outpnt - 10) step -1
                    tget [Y,i] temp4
                    if len(temp4) > 5 and temp4{1,3} = "J B"
                      sub = 5
                      a6 = int(temp4{sub..})
                      a7 = int(temp4{sub..})
                      a8 = int(temp4{sub..})
                      a8 += 10000000
                      a9 = sub
                      temp4 = "J B " // chs(a6) // " " // chs(a7) // " " // chs(a8) // temp4{sub..}
                      tput [Y,i] ~temp4
                      goto PR
                    end
                  repeat
                end
                ++@n
                tcode(@n) = zpd(4)
                tv1(@n) = P_SUGGESTION
                tv2(@n) = 0x0401
              end
              sub = g
              goto MORE_SUGG
            end
          end

          sub = g
          goto MORE_SUGG
        end
        goto PR
      end

      END OF MAIN CODE FOR PRINT SUGGESTIONS
    ==========================================




      if line{8} = " "
        d = 0
      end
      if mrest > 0
        out = trm(line)
        if len(out) > 15       /* this is a normal stage2 data line
          perform setmrest
        else

     03/07/06 allowing only mheavy4 of all measure codes
                to slip through here.

          if "mrib" not_con line{1} or line{1,7} = "mheavy4"
          if line{1,4} <> "meas" and "rib" not_con line{1}
            perform setmrest
          end
        end
      end
      if "ABCDEFGri" con line{1}
        ++@n
        i = NOTE
        if line{1} = "r"
          i = REST
        end
        if line{1} = "i"
          i = IREST
        end
        tv1(@n) = i
        tv2(@n) = d
        if " 123" con line{24}               /* staff number goes in tv3(.) & 0x0000000f
          if mpt = 1
            tv3(@n) = 0
          else
            tv3(@n) = mpt - 2
          end
        else
          putc Illegal character in staff number column (col. 24).  Please fix.
          putc Record = ~line
          goto EE
        end

        Code added 01/30/05 for text under notes

        temp4 = trm(line)
        if len(temp4) > 43
          text_flag = 1
        end


        if " 123456789" con line{15}         /* track number goes in tv3(.) & 0x000000f0
          if mpt = 1                         /* track number = 0 means no information
          else
            tracknum_flag = 1
            --mpt
            a1 = mpt << 4
            tv3(@n) += a1
          end
        else
          putc Illegal character in track number column (col. 15).  Please fix.
          putc Record = ~line
          goto EE
        end

        Code added 01/30/05 for text under notes

        temp4 = trm(line)
        if len(temp4) > 43
          text_flag = 1
        end


        if line{1} = "i"
          tcode(@n) = "ires"                 /* redundant, but do it to be on the safe side
        else
          tcode(@n) = line{1,4}
        end
        tdata(@n,1) = line{17..80}

     Code added 01/03/04 to deal with optional rests (whole and otherwise)

        if "WHQESTXYZ " con line{17}
          a1 = mpt
          if line{1} = "r" and wrest = 1
            tdata(@n,1){1} = "W"

     /* New: This line replaced 10/15/07

            if line{17} = " "
              tdata(@n,1){1} = "o"
            else
              tdata(@n,1){1} = line{17}
            end

          else
            tdata(@n,1){1} = "whqestxyz "{a1}
          end
        end

        if wrest = 1 and line{1} = "r" and line{17} = " "
          tdata(@n){1} = "W"
        end

        if "ri" con line{1}                  /* restplace flag goes in tv3(.) & 0x0000ff00
          if mpt = 1
            tv3(@n) += restplace << 8
          end
        else
          if repeater_flag > 0               /* repeater flag goes in tv3(.) & 0x0000ff00
            tv3(@n) += repeater_flag << 8
            if bit(0,repeater_flag) = 1 and line{26} = "]"
              repeater_flag = 0
            end
          end
        end

    Code added 05/12/04 to implement global suggestion to turn off
    the printing of rests (used for blank continuo parts).  Note that
    no other print suggestions for rest can be inforce when this
    feature is used.

    Adding condition 01/01/06 to make irest_flag work

        if restoff = 1
        if restoff = 1 or (irest_flag = 1 and tv1(@n) = IREST)
          ++@n
          tcode(@n) = zpd(4)
          tv1(@n) = P_SUGGESTION
          tv2(@n) = 0x0300
          tcode(@n){1} = chr(3)
        end



    Code added 01/10/06  to expand the operation of art_flag

        if art_flag >= 16 and "ri" not_con line{1}
          a2 = art_flag >> 4
          if a2 = 1 or a2 = 3 or a2 = 4 or a2 = 8
            ++@n
            tcode(@n) = zpd(4)
            tcode(@n){1} = chr(1)
            tv1(@n) = P_SUGGESTION
            if a2 < 4
              tv2(@n) = 0x0201
            else
              if a2 = 4
                tv2(@n) = 0x0202
              else
                if a2 = 8
                  tv2(@n) = 0x0203
                end
              end
            end
            tcode(@n){1} = chr(3)
          end
        end

        goto PR
      end
      if line{1} = "/"
        perform action
        ++outpnt
        tput [Y,outpnt] J M 0 ~obx  0 0 10000 0 0
        putc END
        goto NEXT
      end
      if " cgf*b" con line{1}
        a2 = mpt
        e = int(line{8})
        if line{8} in ['A'..'E']
        if line{8} in ['A'..'E','X']                    /* Implementing arpeggios 01/13/06
          e = ors(line{8}) - 55        /* A = 10, etc.       X = 33 (ARPEGGIO)
        end

      New code 01/13/06 implementing arpeggios; delete extraneous data

        if e = ARPEGGIO
          line = line{1,24}
          line = line // pad(80)
        end

        ++@n
        tdata(@n,1) = line{17..80}
        if line{1} = "f"
          tv3(@n) = 0
        else
          if " 123" con line{24}             /* staff number goes in tv3(.) & 0x0000000f
            if mpt = 1
              tv3(@n) = 0
            else
              tv3(@n) = mpt - 2
            end
          else
            putc Illegal character in staff number column (col. 24).  Please fix.
            putc Record = ~line
            goto EE
          end
          if a2 < 4         /* chords, grace, and cue notes
            if " 123456789" con line{15}     /* track number goes in tv3(.) & 0x000000f0
              if mpt = 1                     /* track number = 0 means no information
              else
                --mpt
                a1 = mpt << 4
                tv3(@n) += a1
              end
            else
              putc Illegal character in track number column (col. 15).  Please fix.
              putc Record = ~line
              goto EE
            end
          end
        end
        goto T(a2)                     /* a2 = mpt from ~20 lines above
T(1):
        tv1(@n) = XNOTE
        tv2(@n) = 0
        tcode(@n) = line{2,4}
        goto PR
T(2):
        i = CUE_NOTE
        if line{2} = " "
          i = XCUE_NOTE
          tcode(@n) = line{3,4}
          e = 0
        else
          tcode(@n) = line{2,4}
        end
        if line{2} = "r"
          i = CUE_REST
        end
        tv1(@n) = i
        tv2(@n) = e
        if line{2} = "r"                     /* restplace flag goes in tv3(.) & 0x0000ff00
          tv3(@n) += restplace << 8
        else
          if repeater_flag > 0               /* repeater flag goes in tv3(.) & 0x0000ff00
            tv3(@n) += repeater_flag << 8
            if bit(0,repeater_flag) = 1 and line{26} = "]"
              repeater_flag = 0
            end
          end
        end
        goto PR
T(3):
        i = GR_NOTE
        if line{2} = " "
          i = XGR_NOTE
          tcode(@n) = line{3,4}
          e = 0
        else
          tcode(@n) = line{2,4}
        end
        tv1(@n) = i
        tv2(@n) = e
        if repeater_flag > 0                 /* repeater flag goes in tv3(.) & 0x0000ff00
          tv3(@n) += repeater_flag << 8
          if bit(0,repeater_flag) = 1 and line{26} = "]"
            repeater_flag = 0
          end
        end
        goto PR
T(4):
        tv1(@n) = FIGURES
        tv2(@n) = d
        tv3(@n) = 0
        tcode(@n) = line{2,4}
        goto PR
T(5):
        tv1(@n) = MUSICAL_DIR
        if "12345" con line{15}
          tv2(@n) = mpt
        else
          tv2(@n) = 1
        end
        if d > 0
          tv3(@n) += d << 8
        end


 
   These lines added 02/03/08.  Rehearsal feature is not
     implemented in SCORE conversion (for the moment)

#if AUTOSCR
        if line{17} = "R"
          line{17} = "D"
        end
        if line{18} = "R"
          line{18} = "D"
        end
#endif




        tcode(@n) = line{17,4}

     Code added 01/07/06 to give format warning

        if line{17,2} = "  "
          putc WARNING Bad format in a musical direction record
          temp4 = trm(line)
          putc    Rec #~(scnt+5)  -> ~temp4
          putc
        end
     
        goto PR
T(6):
        tv1(@n) = BACKSPACE
        tv2(@n) = d
        tv3(@n) = 0
        tcode(@n) = line{1,4}
        goto PR
      end
      if line{1} = "m"

        ++barnum2
        a1 = measuremap(barnum2,1)
        jscrdat = "| NTRACKS=" // chs(a1)
        if nstaves = 2
          loop for a2 = 1 to 9
            if trackstave(barnum2,a2,1) + trackstave(barnum2,a2,2) > 0
              jscrdat = jscrdat // " (" // chs(a2) // "," // chs(trackstave(barnum2,a2,3)) // ")"
            end
          repeat
        end

        if f4 = 0 and line{2,6} <> "heavy4"

     03/07/06  Allowing other measure types (except "mheavy4") here, but
                 clearing mrest below for all cases other than "measure"

        if line{2,4} = "easu" and f4 = 0
          out = trm(line)
          if len(out) < 16

     New 03/13/06 Don't process for "multi-rests" unless multirest_flag = 1
                  Normally, this will apply to Parts only.

          if len(out) < 16 and multirest_flag = 1
            if @n = 1
              if "ir" con tcode(1){1}
                out = trm(tdata(1,1))
                if out = ""
                  ++mrest
                  if mrest = 1
                    how_much_mrest(1) = divspq
                    how_much_mrest(2) = tv2(1)
                  else
                    if divspq <> how_much_mrest(1)
                      dputc Program error
                      stop
                    end
                    if tv2(1) <> how_much_mrest(2)
                      putc Stage 2 file format error at approx rec ~scnt
                      putc   Attempting to use indefinite rests (rest with no letter)
                      putc   of successively different lengths, without change
                      putc   of meter.
                      putc
                      putc                Program Halted
                      putc
                      stop
                    end
                  end

                  mrest_line = line
                  measnum = g
                  if wrest = 1 or multirest_flag = 0    /* New code 01/03/04 and 03/04/06
                    perform setmrest                    /*  "   "      "
                  else
                    if line{2,4} <> "easu"
                      perform setmrest       /* 03/07/06 clear mrest for non-standard measures
                    end
                  end
                  @n = 0
                  out = trm(line)
                  if len(out) > 7
                    if len(out) > 12
                      out = line{1,8} // chs(g-1) // pad(12)
                      out = out // line{13..}
                      out = trm(out)
                    else
                      out = line{1,8} // chs(g-1)
                      out = trm(out)
                    end
                  end
#if MREPORT
                  putc ~out
#endif

       Added 01/01/06

                  if mreport_flag = 1
                    putc ~out
                  end

                  goto PR
                end
              end
            else
              if @n = vflag * 2 - 1 and nstaves = 1

                examine

                loop for i = 1 to vflag * 2 step 2
                  out = trm(tdata(i,1))
                  if "ir" not_con tcode(i){1} or out <> ""
                    i = 10000
                  else
                    if i < @n
                      out = trm(tdata(i+1,1))
                      if tcode(i+1) <> "back" or out <> ""
                        i = 10000
                      end
                    end
                  end
                repeat
                if i < 10000
                  ++mrest

                  if mrest = 1
                    how_much_mrest(1) = divspq
                    how_much_mrest(2) = tv2(1)
                  else
                    if divspq <> how_much_mrest(1)
                      dputc Program error
                      stop
                    end
                    if tv2(1) <> how_much_mrest(2)
                      putc Stage 2 file format error at approx rec ~scnt
                      putc   Attempting to use indefinite rests (rest with no letter)
                      putc   of successively different lengths, without change
                      putc   of meter.
                      putc
                      putc                Program Halted
                      putc
                      stop
                    end
                  end

                  mrest_line = line
                  measnum = g
                  if wrest = 1 or multirest_flag = 0    /* New code 01/03/04 and 03/04/06
                    perform setmrest                    /*  "   "      "
                  else
                    if line{2,4} <> "easu"
                      perform setmrest       /* 03/07/06 clear mrest for non-standard measures
                    end
                  end
                  @n = 0
                  out = trm(line)
#if MREPORT
                  putc ~out
#endif
                  goto PR

       Added 01/01/06

                  if mreport_flag = 1
                    putc ~out
                  end

                end
              end
            end
          end
        end
        f4 = 0
        ++@n
        tv1(@n) = BAR_LINE
        tv2(@n) = g
        tv3(@n) = nstaves
        measnum = g
        tcode(@n) = line{4,4}
        tdata(@n,1) = line{17..80}
        tdata(@n,2) = chs(barnum2) // "+" // jscrdat
        jscrdat = ""

        if tdata(@n,1) not_con "*" and tdata(@n,1) not_con "&"  /* 2nd condition added 01/30/05
        if tdata(@n,1) not_con "*"
          out = trm(line)
          if len(out) > 7
            if len(out) > 12
              out = line{1,8} // chs(g-1) // pad(12)
              out = out // line{13..}
              out = trm(out)
            else
              out = line{1,8} // chs(g-1)
              out = trm(out)
            end
          end
#if MREPORT
          putc ~out
#endif

       Added 01/01/06

          if mreport_flag = 1
            putc ~out
          end

          perform action
          loop for i = 1 to 50
            loop for j = 1 to 4                         /* 06/04/08 was 3
              measax(j,i) = claveax(i)
              measax(j,i) = tclaveax(i)                 /* New 12/14/07
            repeat
          repeat
          @n = 0
        end
        goto PR
      end
      putc ~line
      trp = 7
      goto trap
*
NEXT:

    Open output file

      open [3,2] outfile

#if AUTOSCR

      putf [3] ~header1
      putf [3] ~header2
      putf [3] ~header3

#else

    New 03/25/06

      tget [X,2] temp2
      if temp2 con "{"
        temp2 = temp2{mpt..}
        temp2 = trm(temp2)
      else
        temp2 = "not identified"
      end
      tget [X,3] temp3
      if temp3 con "TIMESTAMP:"
        temp3 = temp3{11..}
        temp3 = mrt(temp3)
        temp3 = trm(temp3)
      else
        temp3 = ""
      end
      putf [3] @ SOURCE: ~temp2  ~temp3

#endif

      tget [Y,1] a .t1 temp3

      Adding this code 01/30/05 to make sure text is set at the right height
 
      if text_flag = 1
        a = text_loc
      end
      if single_line = 0
        LL = "L"
      else
        LL = "l"
      end

#if AUTOSCR

      temp3 = temp3 // "  "
      a2 = transposition
      a4 = instrument_number

      a1 = measuremap(1,1)
      if nstaves = 2
        line = ""
        loop for a3 = 1 to 9
          if trackstave(1,a3,1) + trackstave(1,a3,2) > 0
            line = line // " (" // chs(a3) // "," // chs(trackstave(1,a3,3)) // ")"
          end
        repeat
        putf [3] L ~granddist  ~a  ~notesize  !39~partname  | NTRACKS=~a1 ~line  | TRANS=~a2  INSTN=~a4
      else
        putf [3] ~LL  0 ~a  ~notesize  !39~partname  | NTRACKS=~a1  | TRANS=~a2  INSTN=~a4
      end

#else

      if nstaves = 2
        putf [3] L ~granddist  ~a  ~notesize  !39~partname
      else
        putf [3] ~LL  0 ~a  ~notesize  !39~partname
      end

#endif

      loop for i = 2 to outpnt
        tget [Y,i] line
        putf [3] ~line
      repeat
      close [3]
      treset [X]
      treset [Y]
*
      ++f3
      if f3 > f2
        stop
      end
      goto BIG
*
trap:
      goto E(trp)
E(1): putc Chord format error
      goto EE
E(2): putc Figured harmony error
      goto EE
E(3): putc Tie error
      putc
      putc This is most often caused by a tie that has no terminating note
      putc in any part.  You should first check to see that all ties in
      putc region where this error occurred are properly terminated.  The
      putc problem can also be caused by excessive durations in a measure
      putc that has a tie.  This will cause the program to think the measure
      putc has ended (early) and it will look for a terminating note in the
      putc next measure; i.b46 e., it will skip a properly placed terminating note.
      putc If you still can't find the error, you might try deleting ties one
      putc at a time to see which one is causing the problem.
      putc
      putc Another cause can be trying to tie notes which are on different
      putc staves of the grand staff.  At the moment, autoset does not support
      putc this feature.
      goto EE
E(4): putc Bar error
      goto EE
E(5): putc Text error
      goto EE
E(6): putc Time signature error
      goto EE
E(7): putc No recognizable control character
      goto EE
E(8): putc Figured harmony out of order
      putc
      putc Possibly you have entered a figured offset improperly.
      putc
      putc For example, the offset to the second figure actually appears
      putc in the record for the first figure.  The interpretation of the
      putc offset number is how must to advance the division counter after
      putc a figure is printed.
      putc
      goto EE
E(9): putc Pitch decoding error
      goto EE

      /* This error condition added 10-12-96
E(10):
      putc No pitch found to match tie termination (X) direction (*).
      putc
      putc Check musical direction records (*) in this measure for tie
      putc terminations and verify that the pitch in column 25 appears
      putc earlier in the measure, on the same staff.
      putc
      goto EE
EE:   putc
      putc    Program Halted
      putc
      stop

                 ┌─────────────────────────────────┐
                 │ End of processing music data    │
                 └─────────────────────────────────┘




                                                                      
              ┌─────────────────────────────────────────┐             
              │          P R O C E D U R E S            │             
              └─────────────────────────────────────────┘             
                                                                      


 ┌──────────────────────────────────────────────────────────────┐
 │P  1a. decodenote                                             │
 │                                                              │
 │    Input: note (string)                                      │
 │                                                              │
 │    Output:    @c = clave number                              │
 │                      100 = rest                              │
 │                      200 = unprinted rest                    │
 │                                                              │
 │               @d = unmodified accidental flag                │
 │                     0000 = no accidental                     │
 │                     0010 = sharp                             │
 │                     0011 = flat                              │
 │                     1010 = sharp sharp                       │
 │                     1111 = flat flat                         │
 │                                                              │
 │               for rests, mf(1) = 0    ?????????????          │
 │                                                              │
 │    Note: decodenote is called only AFTER all note events have│
 │            been reordered by time within the measure.        │
 │                                                              │
 └──────────────────────────────────────────────────────────────┘

      procedure decodenote
        int a,b
        if note = "rest"
          @c = 100
          @d = 0
          mf(1) = 0
          return
        end
        if note = "ires"
          @c = 200
          @d = 0
          return
        end
        if claves con note{1}
          a = mpt
        end
        @d = 0
        loop for b = 2 to 4
          if numbers con note{b}
            @c = mpt - 2 * 7 + a
            return
          end
          @d <<= 2
          if accs con note{b}
            @d = @d | mpt
          end
        repeat
        putc note = ~note     This will cause a ...
      return 9

 ┌────────────────────────────────────────────────────────────────┐
 │P  1a. decodeax (t1,t2)                                         │
 │                                                                │
 │    Input: t1  = pointer into ts array                          │
 │           t2  = index into measax array                        │
 │           bit(18,ts(t1,SUBFLAG_1)) = cautionary accidental flag│
 │            (has effect only when no accidental would           │
 │             otherwise be printed)                              │
 │                                                                │
 │    Output: correct accidental in ts(.,AX)                      │
 │                                                                │
 │             0000 = no accidental                               │
 │             0001 = natural                                     │
 │             0010 = sharp                                       │
 │             0011 = flat                                        │
 │             0110 = natural sharp                               │
 │             0111 = natural flat                                │
 │             1010 = sharp sharp                                 │
 │             1111 = flat flat                                   │
 │                                                                │
 └────────────────────────────────────────────────────────────────┘

      procedure decodeax (t1,t2)
        int t1,t2,t3,t4,ax
        getvalue t1,t2

        t3 = ts(t1,CLAVE)
        if t3 > 99
          ts(t1,AX) = 0
          return
        end

    adjust accident to reflect key and measure

        t4 = ts(t1,AX)
        ax = t4

        if ax = measax(t2,t3)
          if bit(18,ts(t1,SUBFLAG_1)) = 0
            t4 = 0
          else
            if t4 = 0
              t4 = 1        /* natural
            end
          end
        else
          if ax = 0
            t4 = 1
          else
            if measax(t2,t3) > 7
              if ax < 4
                t4 = t4 | 4
              end
            end
          end
          measax(t2,t3) = ax
        end
        ts(t1,AX) = t4
      return

 ┌────────────────────────────────────────────────────────────────────┐
 │P  2. action                                                        │
 │                                                                    │
 │    Purpose:  Action is basically a continuation of the music       │
 │              processing program.  It is called when the data       │
 │              for a measure is complete.                            │
 │                                                                    │
 │    Inputs:  @n = number of elements in data arrays                 │
 │             tv1(.) = element type                                  │
 │                                                                    │
 │                type   element                                      │
 │                ----   -------                                      │
 │                  1    regular note                                 │
 │                  2    extra regular note in chord                  │
 │                  3    regular rest                                 │
 │                  4    cue note                                     │
 │                  5    extra cue note in chord                      │
 │                  6    cue rest                                     │
 │                  7    grace note or grace rest                     │
 │                  8    extra grace note in chord                    │
 │                  9    figured harmony                              │
 │                 10    bar line                                     │
 │                 11    musical direction                            │
 │                 12    invisable rest                               │
 │                 13    backspace                                    │
 │                 14    clef change                                  │
 │                 15    time designation or other directive          │
 │                 16    time change                                  │
 │                 17    change in divspq                             │
 │                 18    key change                                   │
 │                 19    print suggestion                             │
 │                                                                    │
 │                tv2(.) = duration for types 1--9, 12,13             │
 │                       = measure number for type 10                 │
 │                       = track number for type 11 (1 = default)     │
 │                       = new clef number for type 14                │
 │                       = 0 for type 15                              │
 │                       = new time flag for type 16                  │
 │                       = new divspq for type 17                     │
 │                       = new key for type 18                        │
 │                       = type of suggestion for type 19             │
 │                                                                    │
 │                           if between 0 and 7                       │
 │                             0 = force slur 1 over                  │
 │                             1 = force slur 1 under                 │
 │                             2 = force slur 2 over                  │
 │                             3 = force slur 2 under                 │
 │                             4 = force slur 3 over                  │
 │                             5 = force slur 3 under                 │
 │                             6 = force slur 4 over                  │
 │                             7 = force slur 4 under                 │
 │                                                                    │
 │                           if between 8 and 9                       │
 │                             8 = overhanded tie (tips down)         │
 │                             9 = underhanded tie (tips up)          │
 │                                                                    │
 │                           if between 16 and 31 (03-21-97)          │
 │                             bit 0: clear = square tuplet           │
 │                                    set   = round tuplet            │
 │                             bit 1: clear = broken tuplet           │
 │                                    set   = continuous tuplet       │
 │                             bit 2: clear = number outside tuplet   │
 │                                    set   = number inside tuplet    │
 │                                                                    │
 │                           if between 128 and 255                   │
 │                             font = type - 128                      │
 │                                                                    │
 │                           if between 0x100 and 0x1ff               │
 │                             vert and/or horz adj to musical dir    │
 │                                                                    │
 │                           if between 0x200 and 0x2ff               │
 │                             vert and/or horz adj to sub-obj        │
 │                                                                    │
 │                           if between 0x300 and 0x3ff               │
 │                             vert and/or horz adj to note/rest/fig  │
 │                               objects.                             │
 │                                                                    │
 │                           if between 0x400 and 0x4ff               │
 │                             suggestion for barline or measure      │
 │                                                                    │
 │                           if between 0x500 and 0x5ff  New 11/05/05 │                             x adjustment to tuple                  │
 │                               (range -127 to +127)                 │
 │                                                                    │
 │                           if between 0x600 and 0x6ff  New 11/05/05 │                             y adjustment to tuple                  │
 │                               (range -127 to +127)                 │
 │                                                                    │
 │                tv3(.) & 0x000f = staff number  (0 or 1)            │
 │                                                                    │
 │                       For notes, rests and irests                  │
 │                       & 0x00f0 = track number (0 to 9) 0=unknown   │
 │                                                                    │
 │                       For notes,                                   │
 │                       & 0xff00 = value of repeater_flag            │
 │                       For rests,                                   │
 │                       & 0xff00 = value of restplace                │
 │                       For musical directions                       │
 │                       & 0xff00 = value of optional forward         │
 │                                    offset for division counter     │
 │                                                                    │
 │                tv5(.) used for flagging $ data that occurs         │ (New 01/17/04)
 │                         at the beginning of a measure, but         │
 │                         is not typeset immediately                 │
 │                                                                    │
 │              tcode(.) = pitch (rest) for types 1--8                │
 │                       = number of figure fields for type 9         │
 │                           (figured harmony)                        │
 │                       = bar type for type 10                       │
 │                       = musical direction code and position        │
 │                           for type 11                              │
 │                       = "ires" for type 12                         │
 │                       = "back" for type 13                         │
 │                       = "0" or "128" for type 14 (clef change)     │
 │                       = "" for types 15--18                        │
 │                       = for type 19 (print suggestions)            │
 │                           a 4 byte code                            │
 │                                                                    │
 │                         byte 1: 0x01: active flag (0 = inactive)   │
 │                                 0xfe: various meanings             │
 │                         (for ties only)                            │
 │                                 length modification (+128)         │
 │                                   (0 = no data)                    │
 │                         (for start slurs ([{z only)                │
 │                                 curvature modification (+128)      │
 │                                   (0 = no data)                    │
 │                                  (-1 = suppress slur) 04/26/05 │                         (for notes, etc.)                          │
 │                                 upper four bits used to designate  │
 │                                 note head shape.                   │
 │                                    0 = regular                     │
 │                                    1 = x (cymbal crash) 02/19/06 │                                   (2 = diamond)                    │
 │                                                                    │
 │                                                                    │
 │                         byte 2: x-y active flags                   │
 │                                 0x01: active flag (0 = inactive)   │
 │                                 0x02: 0 = x position is relative   │
 │                                       1 = x position is absolute   │
 │                                 0x04: 0 = y position is relative   │
 │                                       1 = y position is absolute   │
 │                         byte 3: x position data (+128) (0=no data) │
 │                         byte 4: y position data (+128) (0=no data) │
 │                                                                    │
 OLD     tdata(.,.) = additional data for types 1--9, 11, 1903/21/03 adding
 │            tdata(.,.) = additional data for types 1--11, 19        │ tdata(.,.) for type 10
 │                                                                    │
 │                                                                    │
 │    Output:  ts(.,.)                                                │
 │                          Description of ts                         │
 │                     --------------------------                     │
 │                                                                    │
 │     Case I:  Notes, Rests, Grace Notes, Cue Notes, Cue Rests       │
 │                 Extra Regular, Grace, and Cue notes in Chords      │
 │                     (types  1--8)                                  │
 │                                                                    │
 │        ts(1) = type:   1 = note                                    │
 │                        2 = extra regular note in chord             │
 │                        3 = rest                                    │
 │                        4 = cue note                                │
 │                        5 = extra cue note in chord                 │
 │                        6 = cue rest                                │
 │                        7 = grace note or grace rest                │
 │                        8 = extra grace note in chord               │
 │                                                                    │
 │        ts(2) = division number (starting with 1)                   │
 │        ts(3) = clave    <100 = clave number                        │
 │                          100 = rest                                │
 │                          101 = movable rest                        │
 │                          200 = irest <--                           │
 │                                                                    │
 │        ts(4) (used initially to store pointer to tcode(.) )        │
 │                                                                    │
 │        ts(4) = accidental flag                                     │
 │                                                                    │
 │           bits 0x0f: 0 = none        6 = natural-sharp             │
 │                      1 = natural     7 = natural-flat              │
 │                      2 = sharp      10 = double sharp              │
 │                      3 = flat       15 = double flat               │
 │                                                                    │
 │           bit  0x10: 0 = regular   1 = "silent"                    │
 │                                                                    │
 │           bits 0xff00: left shift (positioning)                    │
 │                                                                    │
 │                                                                    │
 │        ts(5) = note type                                           │
 │                                                                    │
 │                    1 = 256th note      7 = quarter note            │
 │                    2 = 128th note      8 = half note               │
 │                    3 = 64th note       9 = whole note              │
 │                    4 = 32nd note      10 = breve                   │
 │                    5 = 16th note      11 = longa                   │
 │                    6 = 8th note       12 = eighth with slash       │
 │                                                                    │
 │        ts(6) = dot flag   0 = no dot,  1 = dot,  2 = double dot    │
 │        ts(7) = tuplet flag   0 = no tuplet, # = tuplet             │
 │                      0xff    first number                          │
 │                    0xff00    second number                         │
 │                  0xff0000    x adjustment (128 centered)           │
 │                0xff000000    y adjustment (128 centered)           │
 │                                                                    │
 │        ts(8) = location on staff                                   │
 │        ts(9) = spacing number                                      │
 │       ts(10) = stem/chord flag    bit      clear        set        │
 │                                  -----    -------    ---------     │
 │                                    0      no stem      stem        │
 │                                    1      step up    stem down     │
 │                                    2    single note    chord       │
 │                                    3    first note   extra note    │
 │                                  4-7    (note number in chord)     │
 │                                                                    │
 │       ts(11) = beam flag   0 = no beam                             │
 │                            1 = end beam                            │
 │                            2 = start beam                          │
 │                            3 = continue beam                       │
 │                                                                    │
 │       ts(12) = beam code (up to six digits)                        │
 │                                                                    │
 │                 This is an integer less than 1000000.  The one's   │
 │                 digit is the code for the eighth beam; the         │
 │                 tens digit is the code for the sixteenth beam,     │
 │                 etc.                                               │
 │                                                                    │
 │                        digit    char    meaning                    │
 │                       -------   ----   ---------                   │
 │                          0     blank   no beam                     │
 │                          1       =     continued beam              │
 │                          2       [     begin beam                  │
 │                          3       ]     end beam                    │
 │                          4       /     forward hook                │
 │                          5       \     backward hook               │
 │                          6             simple repeater             │
 │                          7             begin repeated beam         │
 │                          8             end repeated beam           │
 │                                                                    │
 │       ts(13) = local x-offset (for chords)                         │
 │                                                                    │
 │       ts(14) = superflag     bit        set                        │
 │                              -----     --------                    │
 │                               0        tie                         │
 │                               1        begin ~~~~~ without tr.     │
 │                               2        begin ~~~~~ with tr.        │
 │                               3        end ~~~~~                   │
 │                               4        begin tuplet                │
 │                               5        end tuplet                  │
 │                               6        tuple has a bracket         │
 │                               7        bracket is continuous       │
 │                                           (0 = broken)             │
 │                               8        number is inside            │
 │                                           (0 = outside)            │
 │                               9        bracket is round            │
 │                                           (0 = square)             │
 │                                                                    │
 │                              16        tie is editorial (dotted)   │
 │                              17        ~~~ is editorial            │
 │                              18        tuple is editorial          │
 │                                                                    │
 │                                                                    │
 │       ts(15) = slurflag    bit set  meaning                        │
 │                             -------  -------                       │
 │                               0      start slur1 (new slur)        │
 │                               1      stop slur1 (from prev. note)  │
 │                               2      start slur2  (etc.)           │
 │                               3      stop slur2                    │
 │                               4      start slur3                   │
 │                               5      stop slur3                    │
 │                               6      start slur4                   │
 │                               7      stop slur4                    │
 │                                                                    │
 │                                 for editorial slurs                │
 │                                 ───────────────────                │
 │                              16      start slur1 (new slur)        │
 │                              17      stop slur1 (from prev. note)  │
 │                              18      start slur2  (etc.)           │
 │                              19      stop slur2                    │
 │                              20      start slur3                   │
 │                              21      stop slur3                    │
 │                              22      start slur4                   │
 │                              23      stop slur4                    │
 │                                                                    │
 │                                 for both kinds of slurs            │
 │                                 ───────────────────────            │
 │                               8      force slur1                   │
 │                               9      0 = up, 1 = down              │
 │                              10      force slur2                   │
 │                              11      0 = up, 1 = down              │
 │                              12      force slur3                   │
 │                              13      0 = up, 1 = down              │
 │                              14      force slur4                   │
 │                              15      0 = up, 1 = down              │
 │                                                                    │
 │                                 for ties                           │
 │                                 ────────                           │
 │                              24      specify tie orientation       │
 │                              25      0 = overhand; 1 = underhand   │
 │                                                                    │
 │                                                                    │
 │       ts(16) = subflag 1    bit     item                           │
 │                             -----   -------                        │
 │                             0-3     ornaments                      │
 │                                     ---------                      │
 │                                      0 = none                      │
 │                                      1 = turn                      │
 │                                      2 = trill(tr.)                │
 │                                      3 = shake                     │
 │                                      4 = mordent                   │
 │                                      5 = delayed turn              │
 │                                      6 = tremulo  New 01/07/06 │                                     7-15 (available)               │
 │                                                                    │
 │                             4-9     accidental combinations        │
 │                                        with ornaments              │
 │                                     -----------------------        │
 │                                     4-6 accidental above ornament  │
 │                                     7-9 accidental below ornament  │
 │                                                                    │
 │                                     Accidental code                │
 │                                     ---------------                │
 │                                      0 = none                      │
 │                                      1 = sharp-sharp               │
 │                                      2 = flat-flat                 │
 │                                      3 = sharp                     │
 │                                      4 = natural                   │
 │                                      5 = flat                      │
 │                                      6 = (not used)                │
 │                                      7 = (not used)                │
 │                                                                    │
 │                            10--13   dynamics                       │
 │                                     --------                       │
 │                                        0 = none (see also bits 26  │
 │                                        1 = p            to 28)     │
 │                                        2 = pp                      │
 │                                        3 = ppp                     │
 │                                        4 = pppp                    │
 │                                        5 = f                       │
 │                                        6 = ff                      │
 │                                        7 = fff                     │
 │                                        8 = ffff                    │
 │                                        9 = mp                      │
 │                                       10 = mf                      │
 │                                       11 = fp                      │
 │                                       12 = sfp                     │
 │                                       13 = sf                      │
 │                                       14 = sfz                     │
 │                                       15 = rfz                     │
 │                                                                    │
 │                               14    upright fermata                │
 │                               15    inverted fermata               │
 │                                                                    │
 │                               16    print note in cue size         │
 │                               17    editorial accidental           │
 │                               18    cautionary accidental          │
 │                                                                    │
 │                               19    accidental follows trill       │
 │                                       rather than above or below   │
 │                                            (added 11/05/05)        │
 │                                                                    │
 │                            20--23   shape of note head             │
 │                                     ------------------             │
 │                                        0 = regular                 │
 │                                        1 = x (cymbal crash)        │
 │                                        2 -> (un-assigned)          │
 │                                          possibilities include     │
 │                                            normal diamond          │
 │                                            stem centered diamond   │
 │                                            blank (stem only)       │
 │                                            18th century            │
 │                                        (added 02/19/06)            │
 │                                                                    │
 │                               24    overhand back tie              │
 │                               25    underhand back tie             │
 │                                        (added 04/22/08)            │
 │                                                                    │
 │                            26--28   more dynamics (added 10/08/08) │
 │                                     -------------                  │
 │                                        0 = really none             │
 │                                        1 = ffp                     │
 │                                        2 = mfp    (added 01/12/09) │
 │                                        3 = Zf     (added 03/16/09) │
 │                                        4 =                         │
 │                                        5 =                         │
 │                                        6 =                         │
 │                                        7 =                         │
 │                                                                    │
 │                                                                    │
 │       ts(17) = subflag 2    bit     item                           │
 │                            -----    -------                        │
 │                      n       0      down bow                       │
 │                      v       1      up bow                         │
 │                      i       2      spiccato                       │
 │                      .       3      staccato                       │
 │                      =       4      line over dot                  │
 │                      _       5      legato                         │
 │                      >       6      horizontal accent              │
 │                      A       7      vertical sfortzando accent     │
 │                      V       8      vertical sfortzando accent     │
 │                      o       9      harmonic                       │
 │                      Q      10      thumb (*)                      │
 │                      0      11      open string (0)                │
 │                                                                    │
 │                            12-31    fingering (up to 5 numbers)    │
 │                                     ----------                     │
 │                            12-14    first number                   │
 │                                       0 = no number                │
 │                                       1 = finger 1                 │
 │                                       2 = finger 2                 │
 │                                       3 = finger 3                 │
 │                                       4 = finger 4                 │
 │                                       5 = finger 5                 │
 │                              15     substitution bit               │
 │                                       0 = no substitution          │
 │                                       1 = substitution             │
 │                            16-19   (second number, see 12 to 15)   │
 │                            20-23   (third  number)                 │
 │                            24-27   (fourth number)                 │
 │                            28-31   (fifth  number)                 │
 │                                                                    │
 │                                                                    │
 │       ts(18) = used for sorting, later used to indicate position   │
 │                     of virtual note head (for placing slurs and    │
 │                     other articulations and signs).  bit 24        │
 │                     set if modified                                │
 │       ts(19) = used for sorting, later used to indicate global     │
 │                     x-offset for chord groups                      │
 │       ts(20) = index to ASCII tsdata                               │
 │       ts(21) = pass number                                         │
 │       ts(22) = backtie flag (for regular, chord and cue notes)     │
 │                                                                    │
 │                     0 = this note is not backward tied             │
 │                     # = this note is backward tied                 │
 │                                                                    │
 │                 Actually the BACKTIE flag has multiple uses.       │
 │                                                                    │
 │                 (1) When the ts array is first being constructed,  │
 │                 there may be a tie into this group of notes        │
 │                 from a previous measure.  In this case, a tiearr   │
 │                 ROW element has already been constructed.  The     │
 │                 tiearr rows need to be searched and the proper     │
 │                 one found.  This index (+ INT10000) is then        │
 │                 stored as the backtie flag.                        │
 │                                                                    │
 │                 (2) For all other row elements of the ts array,    │
 │                 it is sufficient to store a back pointer to the    │
 │                 ts row that originated the tie.                    │
 │                                                                    │
 │                 (3) When it comes time to process the ts array,    │
 │                 three cases may be encountered.                    │
 │                                                                    │
 │                   (a) There is a non-zero backtie flag, and this   │
 │                   flag is greater than INT10000.  In this case,    │
 │                   the backtie flag (- INT10000) points to a tiearr │
 │                   ROW element, and the tie may be processed.       │
 │                                                                    │
 │                   (b) There is a forward tie from this note.  In   │
 │                   this case, the backtie flag has already been     │
 │                   used to set a tie and the element is now free    │
 │                   for other use.  We can generate a new row element│
 │                   in tiearr, and place the pointer to this element │
 │                   in the backtie flag (the term "backtie" is now   │
 │                   a misnomer).                                     │
 │                                                                    │
 │                   (c) Now when we encounter a non-zero backtie     │
 │                   flag in a new ts ROW, we know this points to a   │
 │                   previous ts row, from which we can get the       │
 │                   pointer to the relevant tiearr ROW in that       │
 │                   ts(,.BACKTIE).                                   │
 │                                                                    │
 │                 For this method to work properly, it is            │
 │                 necessary that backward ties be processed before   │
 │                 forward ties.  When a backward tie is processed    │
 │                 it is important to set the backtie flag to zero.   │
 │                                                                    │
 │       ts(23) = note duration (in divisions)                        │
 │       ts(24) = increment distance flag                             │
 │                                                                    │
 │                0 -- fixed distance (not to be modified by print)   │
 │                # -- variable distance; # = time elaps between      │
 │                     this  node and next node.                      │
 │                     (576 divisions = quarter note)                 │
 │                                                                    │
 │       ts(25) = virtual end of stem (bit 24 set if modified)        │
 │       ts(26) = editorial version of ts(16), subflag 1              │
 │       ts(27) = editorial version of ts(17), subflag 2              │
 │       ts(28) = staff number                                        │
 │       ts(29) = multi-track flag << 2 + mcat flag                   │
 │                                                                    │
 │                multi-track flag                                    │
 │                ────────────────                                    │
 │                0 = this note lies on a staff that has notes from   │
 │                     only one pass (the simplest and most common    │
 │                     situation).                                    │
 │                1 = this note belongs to one of multiple passes     │
 │                     on this staff and all notes on this pass       │
 │                     have stems which point up                      │
 │                2 = this note belongs to one of multiple passes     │
 │                     on this staff and all notes on this pass       │
 │                     have stems which point down                    │
 │                3 = this note belongs to one of multiple passes     │
 │                     on this staff and the notes for at least one   │
 │                     of these passes have stem directions which     │
 │                     are both up and down                           │
 │                                                                    │
 │                mcat flag                                           │
 │                ─────────                                           │
 │                0 = only one independent instrument represented     │
 │                     in this measure (vflag = 1)                    │
 │                1 = more than one independent instrument (vflag > 1)│
 │                     but only one pass and without chords (either   │
 │                     unison part, or single part)                   │
 │                2 = more than one independent instrument (vflag > 1)│
 │                     but only one pass but with chords (more than   │
 │                     one part, but parts are isorhythmic)           │
 │                3 = more than one independent instrument (vflag > 1)│
 │                     and more than one pass (two or more musically  │
 │                     independent parts)                             │
 │                                                                    │
 │       ts(30) = spacing parameter (1 <= spn <= 6913)                │
 │       ts(31) = y position of object (saves time in proc. chords)   │
 │       ts(32) = pointer to extra ts() row element for storing data  │
 │                  on slurs.  Elements 1-6 of new element are for    │
 │                  storing global data on slurs entering and leaving │
 │                  the note.  Elements 7-42 are taken in groups of   │
 │                  three (expanded from two in 05/06/03 code revi-   │
 │                  sion), making a total of 12 such groups.  Each    │
 │                  group describes a slur entering or leaving this   │
 │                  note.  The first element in the group contains    │
 │                  general information + the x-offset; the second    │
 │                  element in the group contains the y-offset.  The  │
 │                  third element in the group contains the integer   │
 │                  equivalent of the 4-byte print suggestion for     │
 │                  the slur.  See TS32 for more information.         │
 │                                                                    │
 │       ts(33) = node shift flag (positive and negative values)      │
 │                                                                    │
 │       ts(34) = track number: 0 if not present                      │
 │       ts(35) = base-40 pitch                                       │
 │       ts(36) = displacement of note head from the definitive       │
 │                    node position (related to GLOBAL_XOFF)          │
 │                  Value = -100  if the displacement is (approx.)    │
 │                                  one notehead to the left <--      │
 │                  Value = 100   if the displacement is (approx.)    │
 │                                  one notehead to the right -->     │
 │                  Otherwise Value = a * INT10000 + b where          │
 │                    a = width of notehead in dots                   │
 │                    b = displacement (right or left) meas. in dots  │
 │                                                                    │
 │       ts(37) = SCORE P5 accidental information                     │
 │                  bits 0-7:  the two digit (fractional) part of P5  │
 │                  bits 8-15: the one digit integer part of P5       │
 │                  bits 16-31:  if non-zero, the number of dots      │
 │                               to the left of the definitive node   │
 │                               position where a CODE-9 natural      │
 │                               must be placed.                      │
 │                                                                    │
 │       ts(38) = SCORE P9 augmentation dot information               │
 │                  if bits 24-31 (0xff000000) are off,               │
 │                    bits 0-7:  the two digit (fractional) part of P9│
 │                    bits 8-15: the dot part of P9 (in 10's & 100's) │
 │                  otherwise,                                        │
 │                    bits 24-31 (0xff000000) contain # of dots       │
 │                    bits 0-23 contain relative dot position(in dots)│
 │                      x position * INT10000 + y position            │
 │                      (must use CODE-9 to set this)                 │
 │                                                                    │
 │       ts(39) = tsr pointer                                         │
 │                                                                    │
 │                                                                    │
 │     Case II:  Figures                                              │
 │                                                                    │
 │        ts(1) = 9                                                   │
 │        ts(2) = division number (starting with 1)                   │
 │        ts(3) = number of figures in this chord                     │
 │        ts(4) = space parameter                                     │
 │        ts(5) = first figure -- position one                        │
 │        ts(6) = first figure -- position two                        │
 │        ts(7) = first start/stop flag for continuation line         │
 │        ts(8) = second figure -- position one                       │
 │        ts(9) = second figure -- position two                       │
 │       ts(10) = second start/stop flag for continuation line        │
 │       ts(11) = third figure -- position one                        │
 │       ts(12) = third figure -- position two                        │
 │       ts(13) = third start/stop flag for continuation line         │
 │       ts(14) = fourth figure -- position one                       │
 │       ts(15) = fourth figure -- position two                       │
 │       ts(16) = fourth start/stop flag for continuation line        │
 │                                                                    │
 │              figure field:  0 = blank                              │
 │                          1-19 = figure                             │
 │                            20 = +                                  │
 │                            21 = x                                  │
 │                            22 = 2+                                 │
 │                            23 = sharp                              │
 │                            24 = 4+                                 │
 │                            25 = 5+                                 │
 │                            26 = 6\                                 │
 │                            27 = 7\                                 │
 │                            28 = natural                            │
 │                            29 = flat                               │
 │                            30 = short continuation line (-)        │
 │                                                                    │
 │              Adding 1000 to figure field (position one) indicates  │
 │                small parantheses around the field.                 │
 │              Adding 2000 to figure field (position one) indicates  │
 │                large parantheses this figure and the one below it. │
 │              Adding 3000 to figure field (position one) indicates  │
 │                large parantheses this figure and the two below it. │
 │                                                (Added 11/16/03)    │
 │                                                                    │
 │              start/stop continuation flag:  0 = none               │
 │                                             1 = stop               │
 │                                             2 = start              │
 │                                             3 = continue           │
 │                                                                    │
 │       ts(20) = minimum space for figure group                      │
 │       ts(21) = pass number                                         │
 │       ts(23) = figure duration in divisions (0 if not given)       │
 │       ts(24) = increment distance flag (see notes)                 │
 │       ts(28) = staff number                                        │
 │                                                                    │
 │     Case III:  Bar Lines                                           │
 │                                                                    │
 │        ts(1) = 10                                                  │
 │        ts(2) = division number (starting with 1)                   │
 │        ts(3) = bar number (0 = none)                               │
 │        ts(4) = bar type                                            │
 │                                                                    │
 │                    1 = regular      5 = double regular             │
 │                    2 = heavy        6 = regular-heavy              │
 │                    3 = dotted       9 = heavy-regular              │
 │                                    10 = heavy-heavy                │
 │                                                                    │
 │        ts(5) = repeat flag                                         │
 │                                                                    │
 │                    0 = no repeats       1 = forward repeat         │
 │                    2 = back repeat      3 = both repeats           │
 │                                                                    │
 │        ts(6) = backward ending flag                                │
 │                                                                    │
 │                    0 = no ending                                   │
 │                    # = ending number: positive = stop ending       │
 │                                       negative = discontinue       │
 │                                                     ending         │
 │                                                                    │
 │        ts(7) = forward ending flag                                 │
 │                                                                    │
 │                    0 = no ending                                   │
 │                    # = ending number                               │
 │                                                                    │
 │        ts(8) = flags                                               │
 │                                                                    │
 │                  bit         set           clear                   │
 │                 -----    ------------     -------                  │
 │                   0      continue ~~~      stop ~~~                │
 │                   1      segno sign         0                      │
 │                   2      fermata over bar   0                      │
 │                   3      fermata under bar  0                      │
 │                                                                    │
 │        ts(9) = space parameter (important for non-contr. bars)     │
 │       ts(10) = number over previous measure: 0 = none              │
 │                                                                    │
 │       ts(20) = index to ASCII tsdata   taken out,                  │
 then put back  03/21/03 │                   The reason for putting this back is that         │
 │                   we need an ASCII string to communicate           │
 │                   the NTRACK data that goes with the barline       │
 │                   object.                                          │
 │                                                                    │
 │       ts(21) = pass number                                         │
 │       ts(28) = number of staves                                    │
 │                                                                    │
 │     Case IV:  Signs, Words, Marks                                  │
 │                                                                    │
 │        ts(1) = type   sign = 11, words = 12, mark = 13             │
 │        ts(2) = division number (starting with 1)                   │
 │        ts(3) = vertical position flag:  1 = below line             │
 │                                         2 = above line             │
 │        ts(4) = sign number                                         │
 │                                                                    │
 │                  0 = no sign                                       │
 │                  1 = segno                                         │
 │                  2 = ped                                           │
 │                  3 = *                                             │
 │                  4 = other letter dynamics                         │
 │                  5 = D.S or D.C. (right justified string)          │
 │                  6 = fine (centered string)                        │
 │                  7 = words (left justified string)                 │
 │                  8 = tie terminator       (added 10-12-96)         │
 │                  9 = rehearsal mark (left justified + box)         │
 │                                           (added 02-03-08)         │
 │                                                                    │
 │        ts(5) = super flag                                          │
 │                                                                    │
 │                  0 = no super-object                               │
 │                  1 = start wedge                                   │
 │                  2 = stop wedge                                    │
 │                  3 = start dashes (after words)                    │
 │                  4 = stop dashes                                   │
 │                  5 = start 8ve up                                  │
 │                  6 = stop  8ve up                                  │
 │                  7 = start 8ve down                                │
 │                  8 = stop  8ve down                                │
 │                  9 = start 15 up                                   │
 │                 10 = stop  15 up                                   │
 │                 11 = start 15 down                                 │
 │                 12 = stop  15 down                                 │
 │                 13 = normal transposition (temporary flag)         │
 │                                                                    │
 │        ts(6) = parameter for words:  optional font designation     │
 │                                                                    │
 │        ts(7) = wedge offset  (for cases where a wedge begins after │
 │                                or stops at a letter dynamic)       │
 │                                                                    │
 │        ts(8) = track number  (useful for multiple wedges, dashes   │
 │                                or transpositions of the same type) │
 │                                                                    │
 │        ts(9) = spacing (for case of isolated mark)                 │
 │                                                                    │
 │       ts(10) = parameter for wedges: wedge spread                  │
 │                                                                    │
 │       ts(11) = parameter for musical directions which are          │
 │                  objects: position shift                           │
 │                                                                    │
 │       ts(12) = special flag for case where this element is         │
 │                  isolated on a division (possibly with other       │
 │                  members of this same group).                      │
 │                                                                    │
 │       ts(13) = parameter for musical directions which are          │
 │                  super-objects: position shift                     │
 │                                                                    │
 │       ts(20) = index to ASCII tsdata                               │
 │                                                                    │
 │       ts(21) = pass number                                         │
 │                                                                    │
 │       ts(22) = backtie flag (for tie terminators) (added 10-12-96) │
 │                                                                    │
 │       ts(28) = staff number                                        │
 │                                                                    │
 │     Case V:  Clef change in middle of a measure                    │
 │                                                                    │
 │        ts(1) = type = 14                                           │
 │        ts(2) = division number (starting with 1)                   │
 │        ts(3) = clef number                                         │
 │        ts(4) = clef font number                                    │
 │        ts(5) = transpostion flag:                                  │
 │                                                                    │
 │                   1 = notes written octave higher than sound       │
 │                   0 = notes written at sound                       │
 │                  -1 = notes written octave lower than sound        │
 │                                                                    │
 │        ts(6) = position on staff                                   │
 │        ts(9) = space parameter                                     │
 │       ts(20) = index to ASCII tsdata                               │
 │       ts(21) = pass number                                         │
 │       ts(28) = staff number                                        │
 │                                                                    │
 │     Case VI:  Time designation in middle of a measure              │
 │                                                                    │
 │        ts(1) = type = 15                                           │
 │        ts(2) = division number (starting with 1)                   │
 │        ts(9) = space parameter                                     │
 │       ts(20) = index to ASCII tsdata                               │
 │       ts(21) = pass number                                         │
 │       ts(28) = staff number                                        │
 │                                                                    │
 │     Case VII:  Meter change in middle of a measure                 │
 │                                                                    │
 │        ts(1) = type = 16                                           │
 │        ts(2) = division number (starting with 1)                   │
 │        ts(3) = time number (100 time numerator + denominator)      │
 │        ts(9) = space parameter                                     │
 │       ts(20) = index to ASCII tsdata                               │
 │       ts(21) = pass number                                         │
 │       ts(28) = number of currently active staves                   │
 │                                                                    │
 │     Case VIII:  Change in number of divisions per quarter          │
 │                                                                    │
 │        ts(1) = type = 17                                           │
 │        ts(2) = division number (starting with 1)                   │
 │        ts(3) = divisions per quarter                               │
 │        ts(9) = space parameter                                     │
 │       ts(20) = index to ASCII tsdata                               │
 │       ts(21) = pass number                                         │
 │                                                                    │
 │       Case IX:  Change in key signature                            │
 │                                                                    │
 │        ts(1) = type = 18                                           │
 │        ts(2) = division number (starting with 1)                   │
 │        ts(3) = new key signature                                   │
 │        ts(4) = old key signature                                   │
 │        ts(9) = space parameter                                     │
 │       ts(20) = index to ASCII tsdata                               │
 │       ts(21) = pass number                                         │
 │       ts(28) = number of currently active staves                   │
 │                                                                    │
 └────────────────────────────────────────────────────────────────────┘

      procedure action
        int t1,t2,t3,t4,t5,t6
        int t7,t8                 /* (added 10-12-96)
        if @n = 0
          return
        end
        passnum = 1

    If there are no pending slurs, then clear the ts array and set sct = 0

        if sct = 0
          loop for a9 = 1 to MAX_OBJECTS
            loop for a10 = 1 to TS_SIZE
              ts(a9,a10) = 0
            repeat
            tsdata(a9) = ""
            tsr(a9) = zpd(TSR_LENG)             /* 05/02/03: was zpd(72)
            ts(a9,TSR_POINT) = a9
          repeat
          outslurs = "00000000"
        else
          if outslurs = "00000000"
            if sct > maxsct
              maxsct = sct
            end
            loop for a9 = 1 to maxsct + 10
              loop for a10 = 1 to TS_SIZE
                ts(a9,a10) = 0
              repeat
              tsdata(a9) = ""
              tsr(a9) = zpd(TSR_LENG)           /* 05/02/03: was zpd(72)
              ts(a9,TSR_POINT) = a9
            repeat
            sct = 0
            old@n = 0
          else
            if sct > maxsct
              maxsct = sct
            end
            loop for a9 = sct+1 to maxsct+10
              loop for a10 = 1 to TS_SIZE
                ts(a9,a10) = 0
              repeat
              tsdata(a9) = ""
              tsr(a9) = zpd(TSR_LENG)           /* 05/02/03: was zpd(72)
              ts(a9,TSR_POINT) = a9
            repeat
          end
        end
        oldsct = sct

    If you are starting a new version of the ts(.) array then
      copy claveax(.) to tclaveax(.)   12/14/07

        if sct = 0
          loop for a9 = 1 to 50
            tclaveax(a9) = claveax(a9)
          repeat
        end



    Store original data in set array

        divpoint = 1
        cuediv = 0
        totdiv = 1
        qflag = 0
        divspq = olddivspq

        loop for a9 = 1 to @n
          tsdata(a9+old@n) = ""
          line = tdata(a9,1)
          tvar1 = tv1(a9)
          tvar2 = tv2(a9)
          if tv3(a9) > 0xff
            if tvar1 <= NOTE_OR_REST
              if tvar1 = REST or tvar1 = CUE_REST
                restplace2 = tv3(a9) >> 8
              else
                repeater_flag2 = tv3(a9) >> 10 + 1
                repeater_flag2 = tv3(a9) >> 8            /* changed 01/01/08
              end
            else
              mdir_offset = tv3(a9) >> 8
            end
            tv3(a9) &= 0xff
          else
            repeater_flag2 = 0
            restplace2 = 0
            mdir_offset = 0
          end

   Deal with situation where there is an irest followed by a
   print suggestion that it should be allocated space

          if tvar1 = IREST
            if a9 < @n and tv1(a9+1) = P_SUGGESTION
              if tv2(a9+1) & 0xff00 = 0x0300
                pcontrol = ors(tcode(a9+1){1})
                if pcontrol = 3 or pcontrol = 5
                  tvar1 = REST                  /* send it through the system
                  tcode(a9) = "rest"            /* as a "regular" rest
                end
              end
            else
              if scr_flag = 1
                tvar1 = REST                    /* send it through the system
                tcode(a9) = "ires"              /* as a "silent" rest (but be careful)
              end
            end
          end
 
   Case I:  notes, rests, cue notes, grace notes,
               extra notes in chords, figures

          if tvar1 <> FIGURES and tvar1 <> P_SUGGESTION
            figdiv = 0
          end
          if tvar1 <= NOTE_OR_REST
            loop for a3 = 1 to 7 step 3
              a4 = a3 + 1
              if tvar1 = a4        /* extra chord tone
                if a9 = 1
                  return 1
                end
                c5 = 1
                loop while tv1(a9-c5) = P_SUGGESTION and a9 > c5 + 1
                  ++c5
                repeat
                if tv1(a9-c5) <> a3
                  if tv1(a9-c5) <> a4
                    return 1
                  end
                else
*  tricky code to set chord bit on first note in chord
                  ts(sct,STEM_FLAGS) += 4   /* sct -> previous array entry
                end
              end
            repeat
            ++sct                                 /* incrementing array pointer sct
            ts(sct,TYPE) = tvar1

     Set DIV (for cue notes)

            if chr(tvar1) in [CUE_NOTE,XCUE_NOTE,CUE_REST]
              if tvar1 <> XCUE_NOTE
                ts(sct,DIV) = divpoint + cuediv
              else
                ts(sct,DIV) = divpoint + cuediv - chorddur
              end
              goto WC
            end

     Set DIV (for regular and grace notes)

            if tvar1 = XNOTE
              ts(sct,DIV) = divpoint - chorddur
            else
              ts(sct,DIV) = divpoint
            end

            cuediv = 0

     In special case of arpeggios 01/13/06, get vertical veriables

            if tvar1 = GR_NOTE and tvar2 = ARPEGGIO
              if line{1} = " "
                ts(sct,ARPEG_TOP) = int(line{2})
              else
                ts(sct,ARPEG_TOP) = int(line{1,2})
              end
              if line{3} = "x"
                ts(sct,ARPEG_FLAG) = granddist
              else
                ts(sct,ARPEG_FLAG) = 0
              end
              if line{4} = " "
                ts(sct,ARPEG_BOTTOM) = int(line{5})
              else
                ts(sct,ARPEG_BOTTOM) = int(line{4,2})
              end
              line{1,7} = "e      "
            end



      Normally at this point, we would decode the note and get
      its clave number and accidental.  The reason we cannot safely
      do this at this time is that the backspace command might
      cause us to insert some accidentals at earlier points in
      the measure.  Because of the current order, these notes
      would not be accidentalized, whereas a later one (from
      an earlier pass) would be.  Also, we would like to allow
      the various passes to run through non-controlling bar
      lines.  In any event, we must put off decoding and other
      calculations that depend on this data until the entries
      can be ordered by time.  In the meantime, we will store
      the a pointer to the proper tcode element in ts(4)

WC:         ts(sct,TEMP4) = a9
            a4 = tvar2                  /* duration field, in this case
            if tvar1 > REST
              a5 = tvar2                /* this will become NTYPE

              if chr(tvar1) in [CUE_NOTE,CUE_REST]

           We must, in this case, try to assign a length to the
           cue-type entity in terms of the current value of divspq.
           The parameter, a4, indicates the note type:

                  1 = 256th note      7 = quarter note
                  2 = 128th note      8 = half note
                  3 = 64th note       9 = whole note
                  4 = 32nd note      10 = breve
                  5 = 16th note      11 = longa
                  6 = 8th note

           Columns 4-6 of the variable line contain tuple modifications
           to the note value

                --a4
                a3 = 1 << a4

            a3 = 64 -->  means quarter note, etc.

                a3 *= divspq

            a3 --> length of notetype as measured in units (64*divspq)

                if line{4} <> " "
                  a4 = int(line{4})
                  if line{4} in ['A'..'Z']
                    a4 = ors(line{4}) - 55   /* A = 10, etc
                  end
                  a8 = a4 / 3
               /* default values for "denominator"
                  if rem = 0
                    a8 *= 2
                  else
                    a8 = a4 - 1
                  end
                  if line{6} <> " "
                    a8 = int(line{6})
                    if line{6} in ['A'..'Z']
                      a8 = ors(line{6}) - 55   /* A = 10, etc
                    end
                  end
                  a3 *= a8
                  a3 /= a4
                  if rem <> 0
                    putc Unable to represent cue note in terms of current
                    putc   value of divisions per quarter
                    putc Push <F9> to terminate
                    examine
                    stop
                  end
                end

            a3 --> length of note measured in units (64*divspq)
                     as modified by tuple information

                if ".:;!" con line{2}              /*  code modified 12-24-96
                  if mpt = 1
                    a3 = a3 / 2 * 3
                  else
                    if mpt = 2
                      a3 = a3 / 4 * 7
                    else
                      if mpt = 3
                        a3 = a3 / 8 * 15
                      else
                        a3 = a3 / 16 * 31
                      end
                    end
                  end
                end

            a3 --> length of note measured in units (64*divspq)
                     as further modified by dot information

                chorddur = a3 / 64
                if rem <> 0
                  putc Unable to represent cue note in terms of current
                  putc   value of divisions per quarter
                  putc Push <F9> to terminate
                  examine
                  stop
                end

                chorddur --> length of measured in units (divspq)

                cuediv += chorddur
              end
            else
              if tvar1 <> XNOTE
                chorddur = a4
                divpoint += a4
                if divpoint > totdiv
                  totdiv = divpoint
                end
              end
              if "zyxtseqhwbL" con line{1}
                a5 = mpt                /* this will become NTYPE
              else
                if "123456789AB" con line{1}
                  a5 = mpt              /* this will become NTYPE
                  ts(sct,SUBFLAG_1) |= 0x010000     /* set small print flag
                else
                  if tvar1 = REST


     New 10/15/07

                    if len(line) > 0
                      if "ZYXTSEQHW" con line{1}
                        a5 = mpt                /* this will become NTYPE with flag
                        a5 += 0x100
                      else
                              Old code


     Code modified 01/03/04 to deal with optional whole rests

                        if len(line) > 0 and line{1} = "W"
                        if line{1} = "o"                         /* o = float New 10/15/07
                          ts(sct,CLAVE) = 2   /* temporary floating rest with optionality
                        else
                          ts(sct,CLAVE) = 1   /* temporary floating rest flag
                        end

                        ts(sct,CLAVE) = 1     /* temporary floating rest flag

                        a5 = WHOLE          /* this will become NTYPE
                      end
                    end
                  else

             Note type is missing, try to construct it.
             (the presence of tuplets will throw this off)

                    putc Missing note type (column 17).  Type Enter to continue.
                    getc
                    putc Attempting to construct note type.
                    a8 = chorddur << 5 / divspq
                    a5 = 1
                    loop while a8 > 0
                      a8 >>= 1
                      ++a5
                    repeat
                  end
                end
              end
            end

     Set NTYPE

            ts(sct,NTYPE) = a5

     Set STAFFLOC (for rests)

            if tvar1 = REST or tvar1 = CUE_REST
              ts(sct,STAFFLOC) = restplace2
            end

     Set NOTE_DUR

            if chr(tvar1) in [GR_NOTE,XGR_NOTE]
              ts(sct,NOTE_DUR) = 0
            else
              ts(sct,NOTE_DUR) = chorddur
            end

            a8 = int(line{4})
            if line{4} in ['A'..'Z']
              a8 = ors(line{4}) - 55
            end
            if a8 > 0

      Code added to account for complex tuples: 5-11-93

              a3 = int(line{6})
              if line{6} in ['A'..'Z']
                a3 = ors(line{6}) - 55   /* A = 10, etc
              end
              a3 *= 1000
              a3 *= 256                     /* New 11/05/05

     Set TUPLE

              ts(sct,TUPLE) = a8 + a3
            end

     Set DOT

            if ".^:^^^;^^^^^^^!" con line{2}     /*  code modified 12-24-96
              ts(sct,DOT) = mpt    /* 1 = single dot; 3 = double dot; 7 = triple dot; 15 =
            end

     New code 11/15/07: a cludge fix to an obscure spacing problem

            if scr_flag = 1 and tcode(a9) = "ires"
              ts(sct,DOT) = 0
            end

            if tcode(a9) <> "rest" and tcode(a9) <> "ires"

╒═════════════════════════════════════════════════════════════════╕
     This calculation must be delayed until after the decoding   
     ---------------------------------------------------------   
             a1 = 52 - ts(sct,3) - cline(.) + c8flag(.)          
             ts(sct,8) = a1 * notesize / 2                       
╘═════════════════════════════════════════════════════════════════╛


     Compute Base-40 value of pitch

              if xdata_flag = 1
                a1 = 0
                if "..C.....D.....E....F.....G.....A.....B" con tcode(a9){1}
                  a1 = mpt
                  if "f.#" con tcode(a9){2}
                    a1 += (mpt - 2)
                  end
                  if "f.#" con tcode(a9){3}
                    a1 += (mpt - 2)
                  end
                  if tcode(a9) con ['0'..'9']
                    a2 = int(tcode(a9){mpt})
                    a1 += (a2 * 40)
                  end
                end
                ts(sct,BASE_40) = a1
              end

     Set STEM_FLAGS   (incomplete)

              a1 = 0
              if "u@d" con line{7}     /*  stem direction "u" or "d"
                a1 = mpt
              end

     New code 12/20/05 implementing general suggestion for setting stem directions

              if stem_change_flag = 0 or stem_change_flag = 3
                if "u@d" con line{7}     /*  stem direction "u" or "d"
                  a1 = mpt
                end
              else
                if stem_change_flag = 1
                  a1 = 0
                else
                  a1 = 2
                end
              end

              if tvar1 = XNOTE
                a1 += 12
              end
              ts(sct,STEM_FLAGS) = a1

     Set BEAM_FLAG


              if "][=" con line{10}
                ts(sct,BEAM_FLAG) = mpt
              else
                ts(sct,BEAM_FLAG) = NO_BEAM
              end

     Set BEAM_CODE

              a4 = 0
              if ts(sct,BEAM_FLAG) > NO_BEAM
                if "[]=" con line{10}
                  a3 = 1
                  loop for a1 = 10 to 15
                    if " =[]/\" con line{a1}
                      a4 = mpt - 1 * a3 + a4
                    end
                    if mpt = 1
                      a1 = 15
                    else
                      a3 *= 10
                    end
                  repeat
                end
              end
              ts(sct,BEAM_CODE) = a4

      I think this is the place to alter the ts array, in the case where
      a repeater is requested


              if repeater_flag2 > 0 and ts(sct,BEAM_FLAG) = END_BEAM



      New code 01/01/08.  Set the repeater_dot_flag.

                repeater_dot_flag = 0
                a3 = repeater_flag2 & 0x03
                if a3 = 3
                  repeater_dot_flag = 1
                end

          End of 01/01/08 code


      Decision Point No. 1:  Decide if repeaters are possible

                a3 = 1
REP2:
                if a4 / a3 > 9
                  a3 *= 10
                  goto REP2
                end
                c6 = bit(1,ts(sct,STEM_FLAGS))
                c7 = ts(sct,NTYPE)

       For purposes of the code that follows, we need to keep track of the
       subscripts which point to real data (i.e. not print suggestions)
       in the data(.), tcode(.), and tv(.) arrays.  We will store these
       "valid" subscripts in the mf(.) array.

                c10 = a9
                c2  = 0                            /* counter for primary type
                c4  = 100                          /* secondary beam break flag
                c14 = 100                          /* secondary beam break flag for threesomes (09/21/08)
                repeater_dot_flag2 = 0             /* added 09/21/08

                loop for a1 = sct to 1 step -1     /* Two exits from this loop:
                                                   /*   To REP1 when ts(a1,BEAM_FLAG) = START_BEAM (below)
                                                   /*   to NO_REP whenever a test "fails"
                  loop while tv1(c10) = P_SUGGESTION
                    --c10
                  repeat
                  mf(a1) = c10
                  --c10

                  if ts(a1,TYPE) < tvar1 or ts(a1,TYPE) > tvar1 + 1
                    goto NO_REP
                  end
                  if ts(a1,TYPE) = tvar1
                    if ts(a1,TUPLE) <> 0
                      c4 = 100000 + (ts(a1,TUPLE) & 0xffff)
                    end
                    a5 = ts(a1,BEAM_CODE) / a3
                    if a5 > 3 or a5 = 0
                      goto NO_REP
                    end
                    if a1 < sct and a5 = 3 and c4 < 100000  /* secondary beam ends and starts again
                      if c4 = 100
                        c4 = 16
                      end
                      if c14 = 100          /* New 09/21/08
                        c14 = 6
                      end


     09/21/08 Working on repeaters:  In the case of secondary beam endings, the following (existing)
              code allows endings only in multiples of 2.  Since multiple passes are made
              through this code, c4 becomes the smallest group size.  Specifically, this
              prevents group sizes of 3 and 6, which common enough to consider.

                      loop while c4 > 1
                        c5 = c2 / c4
                        if rem <> 0
                          c4 >>= 1
                        end
                      repeat while rem <> 0

     09/21/08 I think the solution is to run twosome and threesome tests in parallel.
              A jump to NO_REP occurs when both tests fail.  I will use c14 for this
              test.  (New code)

                      loop while c14 > 1
                        c5 = c2 / c14
                        if rem <> 0
                          c14 >>= 1
                        end
                      repeat while rem <> 0
                      if c4 = 1 and c14 = 1      /* c14 test added 09/21/08
                        goto NO_REP
                      end


                    end
                    ++c2
                    mf2(c2) = a1
                  end
                  if bit(1,ts(a1,STEM_FLAGS)) <> c6 or ts(a1,NTYPE) <> c7 or ts(a1,DOT) > 0
                    goto NO_REP
                  end
                  codes = tdata(mf(a1),1){16,12}
                  if ts(a1,BEAM_FLAG) = START_BEAM
                    if codes con ['-','(',')','[',']','{','}','~','>','.','_','=',',']
                    if codes con ['-',')',']','}','~','>','.','_','=',',']
                           /*  02/19/97 change accomodates slurs starting on beginning of beam
                    if codes con [')',']','}','~',',']
                           /*  01/06/06 change accomodates articulations on beginning of beam
                    if codes con ['~',',']
                           /*  01/13/06 change accomodates slurs ending on beginning of beam
                      goto NO_REP
                    end
                    if codes con ['b','c','h'..'k','n','o','r'..'z','A','E','F','M','Q','S','V']
                    if codes con ['b','c','h'..'k','n','o','r'..'z','A','M','Q','S','V']
                      goto NO_REP
                    end
                    goto REP1
                  end
                  if ts(a1,BEAM_FLAG) = END_BEAM
                    if codes con ['-','(',')','[',']','{','}','~','>','.','_','=',',']
                    if codes con ['-','(','[','{','~','>','.','_','=',',']
                           /*  02/19/97 change accomodates slurs ending on end of beam
                      goto NO_REP
                    end
                  else
                    if codes con ['-','(',')','[',']','{','}','~','>','.','_','=','0'..'5',',',':']
                      goto NO_REP
                    end
                  end
                  if codes con ['b','c','f','h'..'z','A','E','F','M','Q'..'S','V','Z']
                    goto NO_REP
                  end
                repeat

      Case 1:  Check to see if all chords under the beam are the same

REP1:
                chordsize = 1
                chord_tones(1) = tcode(mf(a1))
                loop for a2 = a1 + 1 to sct
                  if ts(a2,TYPE) = tvar1
                    a2 = sct
                  else
                    ++chordsize
                    chord_tones(chordsize) = tcode(mf(a2))
                  end
                repeat

        In case of chord at end of beam, finish building mf(.) array

                c10 = a9 + 1
                last_chordsize = 1
                loop for a2 = sct + 1 to 100000
                  loop while tv1(c10) = P_SUGGESTION
                    ++c10
                  repeat
                  if tv1(c10) = tvar1 + 1
                    mf(a2) = c10
                    if "zyxtseqhwbL" con tdata(c10,1){1}
                      if mpt <> c7            /* NTYPE of last chord tones
                        goto NO_REP
                      end
                    else
                      if "123456789AB" con tdata(c10,1){1}
                        if mpt <> c7          /* NTYPE of last chord tones
                          goto NO_REP
                        end
                      end
                    end
                    ++c10
                    ++last_chordsize
                  else
                    a2 = 100000
                  end
                repeat

                if c4 < 100                   /* secondary beams have breaks

     09/21/08  We need to put the correct value in c4 at this point

                  if c4 = 1
                    c4 = c14
                    dputc Secondary size = ~c4
                  end

                  goto REP3
                end

                loop for a2 = a1 + chordsize to sct
                  if ts(a2,TYPE) <> tvar1
                    goto REP3
                  end
                  c5 = 0
                  loop for c6 = 1 to chordsize
                    checkoff(c6) = 1
                  repeat
REP4:
                  c14 = 0
                  loop for c3 = 1 to chordsize
                    if checkoff(c3) = 1 and chord_tones(c3) = tcode(mf(a2))
                      checkoff(c3) = 0
                      c14 = 1
                      c3 = chordsize
                    end
                  repeat
                  if c14 = 0
                    goto REP3
                  end
                  ++c5
                  if c5 < chordsize
                    ++a2
                    if a2 <= sct
                      if ts(a2,TYPE) <> tvar1 + 1
                        goto REP3
                      end
                    else
                      if "zyxtseqhwbL" con tdata(mf(a2),1){1}
     This was done      if mpt <> c7            /* NTYPE of last chord tones
     earlier              goto NO_REP
                        end
                      end
                      if tv1(mf(a2)) <> tvar1 + 1
                        goto REP3
                      end
                    end
                    goto REP4
                  else
                    if a2 > sct + chordsize - 1
                      goto NO_REP
                    end
                  end
                repeat
 
         At this point, we have determined that all chords under the
            beam are the same.  We must compact all of these notes
            into one note (simplest case).
 
                c3 = sct - a1 / chordsize + 1  /* number of notes
                c5 = ts(a1,NTYPE)
                c6 = 0
                c14 = ts(a1,TUPLE)
                c14 = ts(a1,TUPLE) & 0xffff    /* added 11/05/05
                if c14 > 255                   /* no complex tuples allowed
                  goto NO_REP
                end
                if c14 > 0
                  if c14 = c3
                    c7 = 2
                    loop
                      c5 += 1
                      c8 = c3 / c7
                      if c8 > 1
                        c7 <<= 1
                      end
                    repeat while c8 > 1
                    goto REP5
                  else
                    goto NO_REP                /* if tuple, then # must = group size
                  end
                else
                  if chr(c3) not_in [2,3,4,6,7,8,12,14,15,16,24,28,30,31,32] /* modified 12-24-96
                    goto NO_REP                /* must be representable with note value + dot(s)
                  end
                  c7 = 2
                  loop
                    c5 += 1
                    c8 = c3 / c7
                    if c8 = 1
                      mpt = rem
                      if mpt > 0               /* code modified 12-24-96
                        if mpt = c7 >> 1
                          c6 = 1
                        else
                          if mpt = c7 / 4 * 3
                            c6 = 3
                          else
                            if mpt = c7 / 8 * 7
                              c6 = 7
                            else
                              c6 = 15
                            end
                          end
                        end
                      end
                    else
                      c7 <<= 1
                    end
                  repeat while c8 > 1
                end
REP5:
                if chordsize > 1
                  a9 += chordsize - 1          /* advance a9 over rest of last chord
                end

                c7 = 6
                loop for a2 = 1 to QUARTER - ts(a1,NTYPE) - 1
                  c7 *= 10
                  c7 += 6
                repeat
                ts(a1,BEAM_CODE) = c7                    /* 666... etc


     New code 01/01/08.  Deal with special case of the repeater dot.

                if repeater_dot_flag = 1 and c6 = 0
                  c6 = 1
                end

                loop for a2 = a1 to a1 + chordsize - 1
                  ts(a2,NTYPE)    =  c5
                  ts(a2,DOT)      =  c6
                  ts(a2,NOTE_DUR) *= c3
                  ts(a2,BEAM_FLAG) = NO_BEAM
                  if a2 > a1
                    ts(a2,BEAM_CODE) = 0
                  end
                repeat

      11/20/06 Adding code here that allows a slur over repeated notes with a
               repeater, provided that the slur covers all notes in the group
               and that chordsize = 1.

               Also, clear the rest of the ts array and reset sct

                a3 = 0
                if (ts(a1,SLUR_FLAG) & 0xff) <> 0 and chordsize = 1
                  a2 = ts(a1,SLUR_FLAG) & 0xff
                  codes = line{16,12}

                  if codes con ")" and a2 = 1
                    a3 = 2
                  end
                  if codes con "]" and a2 = 3
                    a3 = 8
                  end
                  if codes con "}" and a2 = 5
                    a3 = 32
                  end
                  if codes con "x" and a2 = 7
                    a3 = 128
                  end
                end

           We have already eliminated those cases where slurs start or end
             within a repeater group. (about 200 lines above)

                if a3 > 0
                  c5 = ts(sct,DIV)
                  c6 = ts(sct,AX)
                  c7 = ts(sct,NOTE_DUR)
                  ts(a1,NOTE_DUR) -= c7
                  loop for a2 = a1 + chordsize to sct
                    loop for c8 = 1 to TS_SIZE
                      if c8 <> TSR_POINT
                        ts(a2,c8) = 0
                      end
                    repeat
                  repeat
                  ++a1
                  ts(a1,TYPE) = NOTE
                  ts(a1,DIV) = c5
                  ts(a1,AX) = c6
                  ts(a1,NOTE_DUR) = c7
                  ts(a1,TEXT_INDEX) = c6
                  ts(a1,PASSNUM) = passnum
                  ts(a1,SLUR_FLAG) = a3

                  End of 11/20/06 addition

                else
                  loop for a2 = a1 + chordsize to sct
                    loop for a3 = 1 to TS_SIZE
                      if a3 <> TSR_POINT
                        ts(a2,a3) = 0
                      end
                    repeat
                  repeat
                end

    01/04/06:  There is a problem when a tuple has been started on a repeater.
               First, tuflag has be set to 1, and has not been reset.  Second,
               the SUPER_FLAG has been set to show a tuple starting, but never
               ending.  I can fix these problems here, but this may be symtomatic
               of problems with other super-objects, such as slurs.  I am not
               going to check this out at this point, but be aware!

                loop for a2 = a1 to a1 + chordsize - 1
                  if ts(a2,SUPER_FLAG) <> 0
                    if (ts(a2,SUPER_FLAG)) & 0x10 <> 0
                      tuflag = 0
                      ts(a2,SUPER_FLAG) &= 0xffef     /* turn off start tuple
                    else
                      putc Warning, SUPER_FLAG is non-zero at a repeater
                      putc at approximately measure number ~measnum
                    end
                  else
                    ts(a2,TUPLE) = 0
                  end
                repeat

                sct = a1 + chordsize - 1
                goto EBL
REP3:

      Case 2:  Check to see if chords under the beam can be arranged
                 in groups of 2, 4, 8, or 16

                 c2 = number of chords
                 mf2(.) = ts subscripts for primary notes of each chord
                 c4 = either: maximum group size
                          or: 100 (no group size limitation)
                          or: >= 1000 (tuples are present; no groups allowed)

                if c4 >= 100000
                  goto REP15       /* 02/19/97 change accomodates tuples
                end
                if c4 = 100
                  c4 = 32
                  loop while c4 > c2 / 2
                    c4 >>= 1
                  repeat
                end
                loop while c4 > 1
                  c3 = c2 / c4
                  if rem <> 0
                    c4 >>= 1
                  end
                repeat while rem <> 0
                c5 = ts(a1,NTYPE)
                c6 = 1
                loop while c5 < EIGHTH
                  c6 <<= 1
                  ++c5
                repeat

                repeater_dot_flag2 = 0        /* New 09/21/08
                if c4 > c6
                  c11 = c4 / 3
                  if rem = 0
                    repeater_dot_flag2 = 1    /* New 09/21/08
                  else
                    c4 = c6                   /* Default from old version
                  end
                end

                dputc c4 = ~c4

                if c4 = 1
                  goto REP15
                end

           c4 is now the largest possible group notes under beam
           Next we investigate the question of whether c4 is a
           "legal" group size.

REP11:

           Look for first (actually last) chord prototype

                c1 = 1                      /* index into mf2
                c3 = mf2(c1)                /* c3 should start as sct
                chordsize = 1
                chord_tones(1) = tcode(mf(c3))
                ++c3
                loop while chordsize < last_chordsize   /*
                  ++chordsize
                  chord_tones(chordsize) = tcode(mf(c3))    /* accumulate chord tones
                  ++c3
                repeat

           Look for additional chords to match prototype

REP9:
                c6 = 1                  /* chord counter
REP8:
                ++c1
                c3 = mf2(c1)            /* ts index to next primary note backward in list
                c5 = 0
                loop for c11 = 1 to chordsize
                  checkoff(c11) = 1
                repeat
REP6:
                c11 = 0
                loop for c12 = 1 to chordsize
                  if checkoff(c12) = 1 and chord_tones(c12) = tcode(mf(c3))
                    checkoff(c12) = 0
                    c11 = 1
                    c12 = chordsize
                  end
                repeat
                if c11 = 0
                  goto REP7                /* this pitch (tcode) was not found in chord
                end
                ++c5
                ++c3
                if c5 < chordsize
                  if c3 = mf2(c1-1)
                    goto REP7              /* this chord is not big enough
                  end
                  goto REP6
                else
                  if c3 <> mf2(c1-1)
                    goto REP7              /* this chord is too big
                  end
                end
                ++c6                       /* "valid" chord found
                if c6 < c4
                  goto REP8
                end

           Set up to look for new chord prototype

                if c1 < c2
                  ++c1                        /* index into mf2
                  c3 = mf2(c1)                /* c3 should start as sct
                  chordsize = 1
                  chord_tones(1) = tcode(mf(c3))
                  ++c3
                  loop while c3 < mf2(c1-1)
                    ++chordsize
                    chord_tones(chordsize) = tcode(mf(c3))    /* accumulate chord tones
                    ++c3
                  repeat
                  goto REP9
                end
                goto REP10                    /* successful pattern match
REP7:
                c4 >>= 1
                if c4 > 1
                  goto REP11
                else
                  goto REP15
                end

        Repeaters on groups of chords will work, if group size = c4

REP10:
                c5 = ts(a1,NTYPE)
                c7 = c4
                c15 = 0
                loop
                  ++c15
                  ++c5
                  c7 >>= 1
                repeat while c7 > 1

                c1 = c2
                c6 = mf2(c2)                     /* position for revised data
REP13:                                           /* loop between groups
                c3 = mf2(c1)
REP12:                                           /* loop within chord
                ts(c3,NTYPE) = c5
                ts(c3,NOTE_DUR) *= c4
                ts(c3,DOT) = repeater_dot_flag2      /* New 09/21/08
                if c3 <> mf2(c1)
                  c13 = NO_BEAM
                  ts(c3,BEAM_CODE) = 0
                else
                  temp3 = chs(ts(c3,BEAM_CODE))
                  c14 = len(temp3)
                  if c1 = c2                     /* beginning of first group
                    c13 = START_BEAM
                    temp3 = "222222"{1,c14}
                  else
                    if c1 = c4                   /* beginning of last group
                      c13 = END_BEAM
                      temp3 = "333333"{1,c14}
                    else
                      c13 = CONT_BEAM
                      temp3 = "111111"{1,c14}
                    end
                  end
                  temp3{1,c15} = "666666"{1,c15}
                  ts(c3,BEAM_CODE) = int(temp3)
                end
                ts(c3,BEAM_FLAG) = c13
                ++c3                             /* next pitch in chord
                if c3 < mf2(c1-1)
                  putc Chord

                  goto REP12
                end
                chordsize = c3 - mf2(c1)

          Move data to revised position

                if c1 <> c2
                  c7 = mf2(c1)                   /* source location; c6 = destination
                  loop for c8 = 1 to chordsize
                    loop for c9 = 1 to TS_SIZE
                      if c9 <> TSR_POINT
                        ts(c6,c9) = ts(c7,c9)
                      end
                    repeat
                    ++c6
                    ++c7
                  repeat
                else
                  c6 += chordsize
                end
                if c1 > c4
                  c1 -= c4
                  goto REP13
                end
                if last_chordsize > 1
                  a9 += last_chordsize - 1    /* advance a9 over rest of last chord
                end

          Clear the rest of the ts array and reset sct

                loop for c8 = c6 to sct
                  loop for c9 = 1 to TS_SIZE
                    if c9 <> TSR_POINT
                      ts(c8,c9) = 0
                    end
                  repeat
                repeat
                sct = c6 - 1
                goto EBL
REP15:

         Alternating case is the only possibility left

      Case 3:  Check to see if chords under the beam alternate
                 in groups of 4, 8, 16, or 32, or a tuple size which is even

                 c2 = number of chords
                 mf2(.) = ts subscripts for primary notes of each chord



            Also allow alternating groups of size 6, 12, and 24 (01/15/06)

                if chr(c2) not_in [4,8,16,32]
                if chr(c2) not_in [4,6,8,12,16,24,32]
                  if c4 > 100000                      /* 02/19/97 change accomodates tuples
                    c4 -= 100000
                    if c4 & 0x01 = 0
                      if c4 = c2 and c4 >= 6
                        goto REP15A
                      end
                    end
                  end
                  goto REP16
                end

           Look for first (actually last) chord prototype

REP15A:
                c1 = 1                      /* index into mf2
                c3 = mf2(c1)                /* c3 should start as sct
                chordsize = 1
                chord_tones(1) = tcode(mf(c3))
                ++c3
                loop while chordsize < last_chordsize   /*
                  ++chordsize
                  chord_tones(chordsize) = tcode(mf(c3))    /* accumulate chord tones
                  ++c3
                repeat

           Check all "odd" chords for a match

                loop for c1 = 3 to c2 - 1 step 2
                  c3 = mf2(c1)          /* ts index to next "odd" primary note backward in list
                  c5 = 0
                  loop for c11 = 1 to chordsize
                    checkoff(c11) = 1
                  repeat
REP17:
                  c11 = 0
                  loop for c12 = 1 to chordsize
                    if checkoff(c12) = 1 and chord_tones(c12) = tcode(mf(c3))
                      checkoff(c12) = 0
                      c11 = 1
                      c12 = chordsize
                    end
                  repeat
                  if c11 = 0
                    goto NO_REP            /* this pitch (tcode) was not found in chord
                  end
                  ++c5
                  ++c3
                  if c5 < chordsize
                    if c3 = mf2(c1-1)
                      goto NO_REP            /* this chord is not big enough
                    end
                    goto REP17
                  else
                    if c3 <> mf2(c1-1)
                      goto NO_REP            /* this chord is too big
                    end
                  end
                repeat

           Look for second (actually penultimate) chord prototype

                c1 = 2                      /* index into mf2
                c3 = mf2(c1)
                chordsize2 = 1
                chord_tones(1) = tcode(mf(c3))
                ++c3
                loop while c3 <> mf2(c1-1)
                  ++chordsize2
                  chord_tones(chordsize2) = tcode(mf(c3))    /* accumulate chord tones
                  ++c3
                repeat

           Check all "even" chords for a match

                loop for c1 = 4 to c2 step 2
                  c3 = mf2(c1)          /* ts index to next "even" primary note backward in list
                  c5 = 0
                  loop for c11 = 1 to chordsize2
                    checkoff(c11) = 1
                  repeat
REP18:
                  c11 = 0
                  loop for c12 = 1 to chordsize2
                    if checkoff(c12) = 1 and chord_tones(c12) = tcode(mf(c3))
                      checkoff(c12) = 0
                      c11 = 1
                      c12 = chordsize2
                    end
                  repeat
                  if c11 = 0
                    goto NO_REP            /* this pitch (tcode) was not found in chord
                  end
                  ++c5
                  ++c3
                  if c5 < chordsize2
                    if c3 = mf2(c1-1)
                      goto NO_REP            /* this chord is not big enough
                    end
                    goto REP18
                  else
                    if c3 <> mf2(c1-1)
                      goto NO_REP            /* this chord is too big
                    end
                  end
                repeat

        At this point, we have determined that there are c2/2 matching
        pairs of chords, and that c2 = 4,6,8,12,16,24 or 32, or an even tuple
        of 6 or greater.  In this situation we may reduce these c2
        entries to two entries.  The duration of each entry is c2/2
        times the old duration.  The old duration determines the number
        of beams; the new duration determines the number of through
        beams.  We are going to have to change the the division number
        for the second member of the group.  It is the same as the
        division number of the (c2/2+1)-th member of the group.



       01/15/06 Code added to deal with alternating groups of size 6, 12, and 24

                c4 = c2 / 2
                c7 = c2 / 3
                if rem = 0
                  ts(c3,DOT) = 1
                  c4 = c2 / 3
                else
                  c4 = c2 / 2
                end

                c5 = ts(a1,NTYPE)
                c7 = c4
                loop
                  ++c5                     /* new duration
                  c7 >>= 1
                repeat while c7 > 1
                if c5 > 6 and c2 < 8       /* don't do a four group of eighths, etc.
                  goto NO_REP
                end

                c15 = 7 - ts(a1,NTYPE)     /* total number of beams
                c14 = 7 - c5               /* number through beams
                if c14 < 0
                  c14 = 0
                end
#if OLD_REPEATERS
                if c5 = 7
                  c5 = 8
                  c14 = c15
                end
#endif
                c15 -= c14                 /* number of shortened beams

          Code added 01/15/06 to allow alternating group sizes of 6, 12, and 24
             with repeaters.  This code gets the DIV variable right
 
                c12 = mf2(c4)
                if ts(c3,DOT) = 1
                  c12 = c4 * 3 / 2         /* because we are counting backward in mf2(.)
                  c12 = mf2(c12)
                else
                  c12 = mf2(c4)
                end

                c12 = ts(c12,DIV)          /* division number for second member

                c6 = mf2(c2)                     /* position for revised data
                c3 = mf2(c2)
REP19:                                           /* loop within first chord
                ts(c3,NTYPE) = c5
                c13 = c2 / 3                     /* 02/19/97  added for 6-tuples, 12-tuples
                if rem = 0
                  ts(c3,DOT) = 1
                end
                ts(c3,NOTE_DUR) *= c4
                if c3 <> mf2(c2)
                  c13 = NO_BEAM
                  ts(c3,BEAM_CODE) = 0
                else
                  temp3 = "777777"{1,c15} // "222222"{1,c14}
                  ts(c3,BEAM_CODE) = int(temp3)
                  c13 = START_BEAM
                end
                ts(c3,BEAM_FLAG) = c13
                ++c3                             /* next pitch in chord
                if c3 < mf2(c2-1)
                  goto REP19
                end
                chordsize = c3 - mf2(c2)
                c6 += chordsize
REP20:                                           /* loop within second chord
                ts(c3,DIV)   = c12
                ts(c3,NTYPE) = c5
                c13 = c2 / 3                     /* 02/19/97  added for 6-tuples, 12-tuples
                if rem = 0
                  ts(c3,DOT) = 1
                end
                ts(c3,NOTE_DUR) *= c4
                if c3 <> mf2(c2-1)
                  c13 = NO_BEAM
                  ts(c3,BEAM_CODE) = 0
                else
                  temp3 = "888888"{1,c15} // "333333"{1,c14}
                  ts(c3,BEAM_CODE) = int(temp3)
                  c13 = END_BEAM
                end
                ts(c3,BEAM_FLAG) = c13
                ++c3                             /* next pitch in chord
                if c3 < mf2(c2-2)
                  goto REP20
                end
                chordsize = c3 - mf2(c2-1)
                c6 += chordsize

                if last_chordsize > 1
                  a9 += last_chordsize - 1    /* advance a9 over rest of last chord
                end

          Clear the rest of the ts array and reset sct

                loop for c8 = c6 to sct
                  loop for c9 = 1 to TS_SIZE
                    if c9 <> TSR_POINT
                      ts(c8,c9) = 0
                    end
                  repeat
                repeat
                sct = c6 - 1
                goto EBL              process array for last member of group

                Note 02/19/97: The goto EBL has been commented out so that
                in the case where a tuple or a slur has been started, it will
                be completed.  This feature has not been fully tested, and
                may cause other problems.  Beware!


REP16:
              end

NO_REP:
            end


     Construct SUPER_FLAG

            a14 = 0                                 /* a14 will become ts(14)
            codes = line{16,12}

     look for starting tuplet

            if ts(sct,TUPLE) > 0
              if tuflag = 0 and codes con "*"
                tuflag = 1
                a1 = mpt
                a14 |= 0x10                         /* begin tuplet
                if codes con "&" and mpt < a1
                  a14 |= 0x40000                    /* editorial tuplet flag 03-21-97
                end
              end
            end

     look for end of ~~~~~

            if ctrflag > 0                          /* ctrflag = continue trill flag
            if ctrflag(passnum) > 0                 /* ctrflag changed to array 12/08/07
              if codes con "c"
              else
                a14 |= 0x08                         /* end ~~~~~
                if ctrflag >= 0x100
                if ctrflag(passnum) >= 0x100
                  a14 |= 0x20000                    /* editorial ~~~ flag 03-21-97
                end
                ctrflag = 0
                ctrflag(passnum) = 0
              end
            end

     look for start of ~~~~~

            if codes con "~"
              if ctrflag = 0
              if ctrflag(passnum) = 0               /* New 12/08/07
                a7 = mpt
                if codes con "&" and mpt < a7
                  ctrflag = 0x0200                  /* editorial start ~~~~~
                  ctrflag(passnum) = 0x0200         /* editorial start ~~~~~
                  a14 |= 0x20000                    /* editorial ~~~ flag 03-21-97
                else
                  ctrflag = 0x02                    /* start ~~~~~
                  ctrflag(passnum) = 0x02           /* start ~~~~~
                end
                if codes con "t"
                  ctrflag <<= 1
                  ctrflag(passnum) <<= 1
                  a14 |= 0x04                       /* begin ~~~ with trill
                else
                  a14 |= 0x02                       /* begin ~~~ without trill
                end
              end
            end

     look for forward tie

            if codes con "-"
              a7 = mpt
              a14 |= 0x01                           /* tie flag
              if codes con "&" and mpt < a7
                a14 |= 0x10000                      /* editorial tie (dotted) 03-21-97
              end
            end

     look for end of tuplet

            if codes con "!" and tuflag = 1
              a7 = mpt
              a14 |= 0x20                           /* end tuplet
              if codes con "&" and mpt < a7
                a14 |= 0x40000                      /* editorial tuplet flag 03-21-97
              end
              tuflag = 0
            end

     Set SUPER_FLAG

#if SUB_EDIT
#else
            a14 &= 0xffff           /* turn off editorial flags 03-21-97
#endif
            ts(sct,SUPER_FLAG) = a14

            a14 = 0
            loop for a1 = 1 to 12
              if codes{a1} = "&"     /* and codes{a1+1} in ['0'..'9']
#if SUB_EDIT
                a14 = 1
#endif
                if codes{a1+1} in ['0'..'9','X']        /* New 05/17/03
                  ++a1
                end
                goto TLP1      /* skip &#
              end
              if "()[]{}zx" con codes{a1}
                --mpt
                a7 = 1 << mpt
                if a14 = 1
                  a7 <<= 16
                end
                ts(sct,SLUR_FLAG) |= a7
                goto TLP1
              end

     look for turns, mordents, and their accidentals (trills taken out 11/05/05)
                     (T) tremulos added 01/07/06

              if "r@wMk" con codes{a1}        /* new code 03/01/97
              if "r@wMkT" con codes{a1}       /* code amended      01/07/06
                a7 = mpt

     Special case of tremulo 01/07/06; no editorial and no accidentals allowed

                if a14 = 0 and a7 = 6
                  ts(sct,SUBFLAG_1) |= a7
                  goto TLP1
                end

                if a14 = 0
                  ts(sct,SUBFLAG_1) |= a7
                else
                  ts(sct,ED_SUBFLAG_1) |= a7
                end

                temp3 = codes // pad(13)
                loop for a3 = a1 + 1 to 13
                repeat while "shbu" con temp3{a3}
                if a3 = a1 + 1
                  goto TLP1
                end
                a7 = 0
                temp3 = codes{a1+1..a3-1}
                a1 = a3 - 1
                if temp3 con "u"
                  temp4 = temp3{mpt..} // "..."
                  if mpt = 1
                    temp3 = ""
                  else
                    temp3 = temp3{1,mpt-1}
                  end
                  if "uss.ubb.us..uh..ub.." con temp4{1,4}
                    a7 = mpt + 3
                    a7 = a7 << 1
                  end
                end
                temp4 = temp3 // "...."
                if "ss..bb..s...h...b..." con temp4{1,4}
                  mpt += 3
                  mpt >>= 2
                  a7 |= mpt
                end
                a7 <<= 4
                if a14 = 0
                  ts(sct,SUBFLAG_1) |= a7
                else
                  ts(sct,ED_SUBFLAG_1) |= a7
                end
                goto TLP1
              end

     New code 11/05/05 for trills and their accidentals

              if codes{a1} = "t"
                a4 = 0                                /* this will be bit 19
                a7 = 2
                if a14 = 0
                  ts(sct,SUBFLAG_1) |= a7
                else
                  ts(sct,ED_SUBFLAG_1) |= a7
                end

                temp3 = codes // pad(13)
                loop for a3 = a1 + 1 to 13
                repeat while "shbuU" con temp3{a3}
                if a3 = a1 + 1
                  goto TLP1
                end

                a7 = 0
                temp3 = codes{a1+1..a3-1}
                a1 = a3 - 1

                if temp3 con "u" or temp3 con "U"
                  temp4 = temp3{mpt..} // "..."
                  if mpt = 1
                    temp3 = ""
                  else
                    temp3 = temp3{1,mpt-1}
                  end
                  if "uss.ubb.us..uh..ub.." con temp4{1,4}
                    a7 = mpt + 3                          /*  4,8,12,16,20
                    a7 = a7 << 1                          /*  8,16,24,32,40  = 8 x (1,2,3,4,5)
                  end
                  if "Uss.Ubb.Us..Uh..Ub.." con temp4{1,4}
                    a7 = mpt + 3                          /*  4,8,12,16,20
                    a7 = a7 >> 2                          /*  1,2,3,4,5
                    a4 = 1
                  end
                end
                temp4 = temp3 // "...."
                if "ss..bb..s...h...b..." con temp4{1,4}
                  mpt += 3
                  mpt >>= 2
                  a7 |= mpt
                end
                a7 <<= 4
                a4 <<= 19
                if a14 = 0
                  ts(sct,SUBFLAG_1) |= a7
                  ts(sct,SUBFLAG_1) |= a4                  /* establish bit 19
                else
                  ts(sct,ED_SUBFLAG_1) |= a7
                  ts(sct,ED_SUBFLAG_1) |= a4               /* establish bit 19
                end
                goto TLP1
              end
                             End of 11/05/05 New Code

              if "FE@^+" con codes{a1}
              if "^+@@@@FE" con codes{a1}    accidental flags moved 03/01/97
                mpt += 7
                mpt += 13
                a7 = 1 << mpt
                if a14 = 0
                  ts(sct,SUBFLAG_1) |= a7
                else
                  ts(sct,ED_SUBFLAG_1) |= a7
                end
                goto TLP1
              end

     look for dynamics   (This section recoded 10/08/08 to simplify and add extra dynamic combinations)

              if "mpfZR" con codes{a1}
                if mpt < 4
                  if mpt = 1
                    if "pf" con codes{a1+1}
                      a7 = mpt + 8             /* mp = 9; mf = 10            9  10
                      ++a1
                    else
                      a7 = 0
                    end
                  else
                    a7 = mpt - 2 * 4 + 1       /* p = 1; f = 5               1  5
                    if "pf" con codes{a1+1}
                      ++a1
                      if codes{a1-1} <> codes{a1}
                        if codes{a1} = "p"
                          a7 = 11              /* fp = 11                   11
                        end
                      else
                        ++a7                   /* pp = 2; ff = 6             2   6
                        if codes{a1} = codes{a1+1}
                          ++a1
                          ++a7                 /* ppp = 3; fff = 7           3   7
                          if codes{a1} = codes{a1+1}
                            ++a1
                            ++a7               /* pppp = 4; ffff = 8         4   8
                          end
                        end
                      end
                    else
                      if a7 = 5 and codes{a1+1} = "z"
                        a7 = 13                /* fz = 13                   13
                        ++a1
                      end
                    end
                  end
                else
                  if mpt = 4 and a1 < len(codes) and codes{a1+1} = "p"    /* Zp = sfp
                    a7 = 12                                                 12
                    ++a1
                  else
                    a7 = mpt + 10            /* Z = sfz = 14; R = rfz = 15  14   15
                  end
                end
                a7 <<= 10


           New code 10/08/08

                a7 = 0
                temp4 = codes // pad(13)    /* so we don't run off at the end
                temp3 = temp4{a1}
                loop while "pf" con temp4{a1+1}
                  temp3 = temp3 // temp4{a1+1}
                  ++a1                      /* this will rightsize a1
                repeat
                temp3 = temp3 // pad(4)
                temp3 = temp3{1,4}
                temp3 = temp3 // "."        /* max data length = 4; full padded length = 5
                if "p   .pp  .ppp .pppp.f   .ff  .fff .ffff.mp  .mf  .fp  .Zp  .fz  .Z   .R   ." con temp3
                  a7 = mpt + 4 / 5          /* values 1 to 15
                  a7 <<= 10                 /* range in bits 0x3c00
                end

                if "ffp .mfp .Zf  ." con temp3
                  a7 = mpt + 4 / 5          /* 1 or 2 or 3 New 03/16/09
                  a7 = 1
                  a7 <<= 26                 /* range in bits 0x1c000000
                end

              End of new code 10/08/08

                if a14 = 0
                  if ts(sct,SUBFLAG_1)    & 0x1c003c00 = 0    /* changed 10/08/08 from 0x3100
                    ts(sct,SUBFLAG_1) |= a7
                  end
                else
                  if ts(sct,ED_SUBFLAG_1) & 0x1c003c00 = 0    /* changed 10/08/08 from 0x3100
                    ts(sct,ED_SUBFLAG_1) |= a7
                  end
                end
                goto TLP1
              end

     look for back ties   New 04/22/08

              if "JK" con codes{a1}
                a7 = 1 << (mpt + 23)
                ts(sct,SUBFLAG_1) |= a7
                goto TLP1
              end

     other directions connected with notes

              if "nvi.=_>AVoQ0" con codes{a1}
                --mpt
                a7 = 1 << mpt
                if a14 = 0
                  ts(sct,SUBFLAG_2) |= a7
                else
                  ts(sct,ED_SUBFLAG_2) |= a7
                end
                goto TLP1
              end

     fingering connected with notes

              if "12345" con codes{a1}
                a4 = mpt
                a7 = 0
                a3 = 0
FINNN:
                if a1 < len(codes) and "12345:" con codes{a1+1}
                  if mpt = 6
                    a4 += 8
                  else
                    a4 <<= a3
                    a7 += a4
                    a4 = mpt
                    a3 += 4
                  end
                  ++a1
                  goto FINNN
                end
                a4 <<= a3
                a7 += a4
                a7 <<= 12
                if a14 = 0
                  ts(sct,SUBFLAG_2) |= a7
                else
                  ts(sct,ED_SUBFLAG_2) |= a7
                end
                goto TLP1
              end
TLP1:
            repeat
            tsdata(a9+old@n) = line{28..}

            ts(sct,TEXT_INDEX) = a9 + old@n
            ts(sct,PASSNUM) = passnum
            ts(sct,STAFF_NUM) = tv3(a9) & 0x000f
            ts(sct,TRACK_NUM) = tv3(a9) >> 4 & 0x000f
            goto EBL
          end

   Case II:  figures

          if tvar1 = FIGURES
            ++sct
            ts(sct,TYPE) = tvar1
            if figdiv = 0
              figdiv = divpoint
            end
            ts(sct,DIV) = figdiv
            ts(sct,FIG_DUR) = tvar2
            figdiv += tvar2
            a3 = sct - 1
            a4 = 0
            loop while a3 > oldsct
              if ts(a3,TYPE) = FIGURES
                a4 = a3
              end
              --a3
            repeat while a4 = 0
*   a4 = pointer to previous figure data in measure (or 0)
            ts(sct,NUMBER_OF_FIG) = int(tcode(a9))
            if ts(sct,NUMBER_OF_FIG) > 4
              return 2
            end
            a7 = FIG_DATA
            loop for a5 = 1 to ts(sct,NUMBER_OF_FIG)
              line = mrt(line)

              out = rev(line)
              out = trm(out)
              line = rev(out)

              if line = ""
                return 2
              end

     Adding new code 11/16/03 to allow for parentheses around figure fields

              a13 = 0                           /* initialize parentheses flag to null
              line = line // " "
              if line{1} = "("
                if line con ")"
                  a6 = mpt - 1
                  if mpt = 2
                    return 2
                  end
                  a13 = 1
                  temp = line{2..(mpt-1)}       /* section of line inside ()
                  if temp{1} = " "
                    return 2
                  end                           /* section starts with non-blank field
WB1a:
                  if temp con " "
                    temp = temp{mpt..}          /* skip over non-blank field
                    temp = mrt(temp)            /* and remove leading blanks to next field
                    if temp = ""
                      return 2
                    end
                    ++a13
                    goto WB1a
                  end
                  if a13 > (ts(sct,NUMBER_OF_FIG) - a5 + 1)
                    return 2
                  end
                  a13 *= 1000
                  line = line{2..a6}            /* now remove parentheses from line
                else
                  return 2
                end
              end

              if line con " "
                temp = line{1,mpt-1}
                line = line{mpt..}
              end

              temp = temp // pad(3)
              if "_-" con temp{1}
                if mpt = 1
                  if a4 = 0
                    return 2
                  end
                  if ts(a4,a7+2) = 0
                    ts(a4,a7+2) = 2
                  else
                    ts(a4,a7+2) = 3
                  end
                  ts(sct,a7+2) = 1
                else
                  ts(sct,a7) = 30                         /* 30
                end
              else
                if "x@#@@@@nf" con temp{1}                /* 21,23,28,29
                  ts(sct,a7) = mpt + 20
                  a6 = 2
                  goto WB1
                end
                if "2@45" con temp{1} and temp{2} = "+"   /* 22,24,25
                  ts(sct,a7) = mpt + 21
                  a6 = 4
                  goto WB1
                end
                if "/\" con temp{2} and "67" con temp{1}  /* 26,27
                  ts(sct,a7) = mpt + 25
                  a6 = 4
                  goto WB1
                end
                a6 = int(temp)                            /* 1..19
                if a6 < 0 or a6 > 19
                  return 2
                end
                ts(sct,a7) = a6
                if ts(sct,a7) < 10
                  a6 = 2
                else
                  a6 = 3
                end
WB1:            if a6 < 4
                  temp = temp{a6..}
                  if "+x@#@@@@nf" con temp{1}
                    ts(sct,a7+1) = mpt + 19
                  else
                    ts(sct,a7+1) = int(temp)
                  end
                end
              end
              ts(sct,a7) += a13                  /* Adding parentheses flag 11/16/03
              a7 += 3
            repeat
            ts(sct,TEXT_INDEX) = a9              Removing this line
            ts(sct,PASSNUM) = passnum
            ts(sct,STAFF_NUM) = nstaves - 1
            goto EBL
          end

   Case III:  bar lines

          if tvar1 = BAR_LINE
            ++sct
            ts(sct,TYPE) = tvar1
            ts(sct,DIV) = divpoint
            ts(sct,BAR_NUMBER) = tvar2
            if tcode(a9) = "sure"
              ts(sct,BAR_TYPE) = REGULAR
            else
              if "@1d@e2@@34" con tcode(a9){4}
                ts(sct,BAR_TYPE) = mpt
              end
            end
            if line con ":|"
              ts(sct,REPEAT) |= 0x02
            end
            if line con "|:"
              ts(sct,REPEAT) |= 0x01
            end
            if line con "stop-end"
              ts(sct,BACK_ENDING) = int(line{mpt+8..})
            end
            if line con "start-end"
              ts(sct,FORW_ENDING) = int(line{mpt+9..})
            end
            if line con "disc-end"
              a3 = int(line{mpt+8..})
              ts(sct,BACK_ENDING) = 0 - a3
            end

        12/08/07  ctrflag made into an array

            if ctrflag > 0 and line con "~"
            if line con "~"
              loop for a7 = 1 to passnum
                if ctrflag(a7) > 0
                  ts(sct,BAR_FLAGS) |= 0x01
                end
              repeat
            end
         
            if line con "A"
              ts(sct,BAR_FLAGS) |= 0x02
            end
            if line con "F"
              ts(sct,BAR_FLAGS) |= 0x04
            end
            if line con "E"
              ts(sct,BAR_FLAGS) |= 0x08
            end
            ts(sct,SPACING) = hpar(37)
            ts(sct,M_NUMBER) = m_number
            if m_number > 0
              ++m_number
            end

            ts(sct,TEXT_INDEX) = a9           Removing this line
            ts(sct,TEXT_INDEX) = a9 + old@n   /* and putting it back 03/21/03
            tsdata(a9+old@n) = tdata(a9,2)    /* and adding this line 03/21/03

            ts(sct,PASSNUM) = passnum
            ts(sct,NUM_STAVES) = tv3(a9)
            goto EBL
          end

   Case IV:  signs, words, marks

          if tvar1 = MUSICAL_DIR
            ++sct
            a4 = 0
            temp = tcode(a9)
            loop for a3 = 1 to 2
              if "APQG" con temp{a3}
                ts(sct,TYPE) = SIGN
                ts(sct,SIGN_TYPE) = mpt
              end
              if temp{a3} = "X"                /* (added 10/12/96)
                ts(sct,TYPE) = SIGN
                ts(sct,SIGN_TYPE) = TIE_TERM
              end
              if "BCD" con temp{a3}
                ts(sct,TYPE) = WORDS
                ts(sct,SIGN_TYPE) = mpt + 4
              end
              if "R" con temp{a3}              /* (added 02/03/08)
                ts(sct,TYPE) = WORDS
                ts(sct,SIGN_TYPE) = REH_MARK
              end
              if "EFHJ" con temp{a3}
                ts(sct,SUPER_TYPE) = mpt
                if mpt < 3
                  a4 = int(line{5..7})   /* get numerical parameter for wedges
                  ts(sct,WEDGE_SPREAD) = a4 * notesize / 10
                end
              end
              if "UWV" con temp{a3}
                if mpt = 2
                  ts(sct,SUPER_TYPE) = NORMAL_TRANS
                else
                  ts(sct,SUPER_TYPE) = mpt + 4       /* 5 or 7 */
                  if int(tdata(a9,1){5,3}) <> 0
                    ts(sct,SUPER_TYPE) += 4
                  end
                end
              end
            repeat
            if ts(sct,TYPE) = 0
              ts(sct,TYPE) = MARK
            end
            ts(sct,DIV) = divpoint + cuediv
            ts(sct,DIV) += mdir_offset
            if temp{3} = "+"
              ts(sct,SIGN_POS) = ABOVE
            else
              ts(sct,SIGN_POS) = BELOW
            end
            if a4 = 0
              a4 = int(line{5..7})
              ts(sct,FONT_NUM) = a4    /* get numerical parameter for words, etc.
            end

            ts(sct,WEDGE_OFFSET) = vpar(1)
            if ts(sct,SUPER_TYPE) = WEDGES << 1    /* end of wedge
              if ts(sct,WEDGE_SPREAD) = 0          /* point of wedge
                ts(sct,WEDGE_OFFSET) = notesize
              end
            end

            if ts(sct,SIGN_TYPE) = LETTER_DYNAM
              if ts(sct,SUPER_TYPE) = 1        /* start wedge
                line = trm(line)
                line = line // pad(9)
                temp = line{9..}

     Adjust temp for "Zp", "Z", and "R".

                temp = " " // temp // " "
                if temp con "Zp"
                  temp = temp{1..mpt-1} // "sfp" // temp{mpt+2..}
                end
                if temp con "Z"
#if SFZ
                  temp = temp{1..mpt-1} // "sfz" // temp{mpt+1..}
#else
                  temp = temp{1..mpt-1} // "sf" // temp{mpt+1..}
#endif
                end
                if temp con "R"
#if SFZ
                  temp = temp{1..mpt-1} // "rfz" // temp{mpt+1..}
#else
                  temp = temp{1..mpt-1} // "rf" // temp{mpt+1..}
#endif
                end
                temp = temp{2..}
                temp = trm(temp)
                a5 = notesize / 2

                loop for a4 = 1 to len(temp)
                  if "pmfszr" con temp{a4}
                    mpt += 59
                    a5 += hpar(mpt)
                  end
                repeat
                ts(sct,WEDGE_OFFSET) = a5
              end
              if ts(sct,SUPER_TYPE) = 2        /* stop wedge
                ts(sct,WEDGE_OFFSET) = 0 - hpar(46)
              end
            end
            if ts(sct,SIGN_TYPE) = CENTER_STR or ts(sct,SIGN_TYPE) = LEFT_JUST_STR
              if ts(sct,SUPER_TYPE) = 1        /* start wedge
                if len(line) > 8
                  ttext = line{9..}
                  ttext = trm(ttext)

        Introducing optional conversion to ligitures in words before a wedge  04/22/04

                  if ligit_flag = 1
                    if ttext = "ff"
                      ttext = "f\@f"
                    end
LIGCON4:
                    if ttext con "ffi"
                      ttext{mpt,3} = "\0:"
                      goto LIGCON4
                    end
                    if ttext con "ffl"
                      ttext{mpt,3} = "\0;"
                      goto LIGCON4
                    end
                    if ttext con "ff"
                      ttext{mpt,2} = "\0<"
                      goto LIGCON4
                    end
                    if ttext con "fi"
                      ttext{mpt,2} = "\0="
                      goto LIGCON4
                    end
                    if ttext con "fl"
                      ttext{mpt,2} = "\0>"
                      goto LIGCON4
                    end
                  end
#if AUTOSCR
#else
                  perform kernttext            /* New 04/22/04
#endif
                  c5 = mtfont
                  perform wordspace
 │    Outputs:    a5 = space taken up by word
                  if ts(sct,SIGN_TYPE) = CENTER_STR   /* centered word
                    a5 >>= 1
                  end
                  a5 += notesize / 2
                  ts(sct,WEDGE_OFFSET) = a5
                end
              end
              if ts(sct,SUPER_TYPE) = 2        /* stop wedge
                ts(sct,WEDGE_OFFSET) = 0 - notesize
              end
            end
            tsdata(a9+old@n) = line{9..}
            ts(sct,TEXT_INDEX) = a9 + old@n
            ts(sct,PASSNUM) = passnum
            ts(sct,STAFF_NUM) = tv3(a9)
            ts(sct,S_TRACK_NUM) = tvar2
            goto EBL
          end

   Case V, VI, VII and VIII:
      clef change, time designation, meter change, divspq change

          if chr(tvar1) in [CLEF_CHG,DESIGNATION,METER_CHG,DIV_CHG]
            ++sct
            ts(sct,TYPE) = tvar1
            ts(sct,DIV) = divpoint
            ts(sct,3) = tvar2               /* first parameter
            if tvar1 = CLEF_CHG
              ts(sct,CLEF_FONT) = int(tcode(a9))
            end
            tsdata(a9+old@n) = tdata(a9,1)
            ts(sct,TEXT_INDEX) = a9 + old@n
            ts(sct,PASSNUM) = passnum
            ts(sct,STAFF_NUM) = tv3(a9)
            ts(sct,DOLLAR_SPN) = tv5(a9)    /* added 01/17/04
        assure proper current value of divspq for this loop
            if tvar1 = DIV_CHG
              qflag = 1
              divspq = tvar2
            end
            goto EBL
          end

   Case IX: key change

          if tvar1 = AX_CHG
            ++sct
            ts(sct,TYPE) = tvar1
            ts(sct,DIV) = divpoint
            ts(sct,3) = tvar2               /* new key
            ts(sct,4) = key                 /* old key
            tsdata(a9+old@n) = tdata(a9,1)
            ts(sct,TEXT_INDEX) = a9 + old@n
            ts(sct,PASSNUM) = passnum
            ts(sct,NUM_STAVES) = tv3(a9)
            ts(sct,DOLLAR_SPN) = tv5(a9)    /* added 01/17/04



      New 12/14/07:  This code adjusts tclaveax(.) to reflect
        the current situation

            loop for a6 = 1 to 50
              tclaveax(a6) = 0
            repeat

            a6 = tvar2
            if a6 > 0
              a7 = 4
              loop for a8 = 1 to a6
                loop for c5 = a7 to 50 step 7
                  tclaveax(c5) = 2
                repeat
                a7 += 4
                if a7 > 7
                  a7 -= 7
                end
              repeat
            end
            if a6 < 0
              a6 = 0 - a6
              a7 = 7
              loop for a8 = 1 to a6
                loop for c5 = a7 to 50 step 7
                  tclaveax(c5) = 3
                repeat
                a7 -= 4
                if a7 < 1
                  a7 += 7
                end
              repeat
            end

            loop for a6 = 1 to 50
              loop for a7 = 1 to 4              /* 06/04/08 was 3
                measax(a7,a6) = tclaveax(a6)
              repeat
            repeat

                    End of 12/14/07 addition 

            goto EBL
          end

   Case X: irst, backspace

          if tvar1 = IREST
            divpoint += tvar2
            if divpoint > totdiv
              totdiv = divpoint
            end
            cuediv = 0
            goto EBL
          end
          if tvar1 = BACKSPACE
            ++passnum
            divpoint -= tvar2
            cuediv = 0
            goto EBL
          end

   Case XI: print suggestions

          if tvar1 = P_SUGGESTION
            if tvar2 < 8                    /* forced slur suggestion
              a3 = tvar2 & 0x06
              a4 = tvar2 & 0x01
              a4 <<= 1
              ++a4                          /* 1 = over; 3 = under
              a4 <<= a3 + 8
              ts(sct,SLUR_FLAG) |= a4       /* turn on forced slur flag
              goto EBL
            end
            if tvar2 < 10
              if tvar2 = 8
                ts(sct,SLUR_FLAG) |= 0x1000000    /* overhanded tie
              else
                ts(sct,SLUR_FLAG) |= 0x3000000    /* underhanded tie
              end
              goto EBL
            end
            if tvar2 < 32
              ts(sct,SUPER_FLAG) |= 0x40          /* tuplet has a bracket 03-21-97
              if bit(0,tvar2) = 1
                ts(sct,SUPER_FLAG) |= 0x200       /* bracket is round 03-21-97
              end
              if bit(1,tvar2) = 1
                ts(sct,SUPER_FLAG) |= 0x80        /* bracket is continuous 03-21-97
              end
              if bit(2,tvar2) = 1
                ts(sct,SUPER_FLAG) |= 0x100       /* tuplet number is inside 03-21-97
              end
              goto EBL
            end
            if tvar2 >= 0x100 and tvar2 < 0x200   /* musical direction
              a3 = ors(tcode(a9){1})
              if a3 > 0
                ts(sct,FONT_NUM) = a3
              end
              a3 = ors(tcode(a9){2}) << 8 + ors(tcode(a9){3})
              if tvar2 & 0xff = 0
                ts(sct,POSI_SHIFT1) = a3 << 8 + ors(tcode(a9){4})
              else
                ts(sct,POSI_SHIFT2) = a3 << 8 + ors(tcode(a9){4})
              end
              goto EBL
            end
            if tvar2 & 0xff00 = 0x0200      /* position of ornaments, etc.
              a3 = tvar2 & 0xff * 4 + 1
              tsr(sct){a3,4} = tcode(a9){1,4}
              goto EBL
            end
            if tvar2 & 0xff00 = 0x0300      /* printing of actual objects
              a3 = ors(tcode(a9){1})
              if a3 > 6
                a3 >>= 1
                a3 &= 0x07
                              3 = print object, no extension dot
                              4 = print object, include extension dot
                              5 = double note length, no extension dot
                              6 = double note length, include extension dot
                              7 = quadruple note length, no extension dot
                if a3 > 2
                  if a3 = 4 or a3 = 6
                    ts(sct,DOT) = 1
                  else
                    ts(sct,DOT) = 0
                  end
                  if a3 > 4
                    ++ts(sct,NTYPE)
                  end
                  if a3 > 6
                    ++ts(sct,NTYPE)
                  end
                  ts(sct,SUPER_FLAG) &= 0xfffffffe  /* turn off ties
                end
              end
              tsr(sct){1,4} = tcode(a9){1,4}
              goto EBL
            end

        New Code 05/25/03 and 05/28/05

            if tvar2 & 0xff00 = 0x0400      /* print suggestion for preceding bar line
              putc Handling measure print suggestion
              putc value of outpnt = ~outpnt
              loop for c1 = outpnt to 1 step -1
                tget [Y,c1] line
                putc rec = ~c1  line = ~line
                if line{1,3} = "J B"
                  sub = 5
                  c2 = int(line{sub..})           /* bar number
                  c3 = int(line{sub..})           /* obx
                  c4 = int(line{sub..})           /* oby
                  temp = line{sub..}
                  if tvar2 & 0xffff = 0x0400
                    c4 += 1000000                 /* 1 million is flag for fixed length
                  else
                    if tvar2 & 0xffff = 0x0401
                      c4 += 10000000              /* New 05/28/05 10 million is flag for
                    end                           /* mid-movement right justification
                  end
                  line = "J B " // chs(c2) // " " // chs(c3) // " " // chs(c4) // temp
                  tput [Y,c1] ~line
                  putc new line = ~line
                  c1 = 1
                end
              repeat
              goto EBL
            end

        New code 11/05/05 for implementing location suggestions for tuples

            if tvar2 & 0xff00 = 0x0500      /* print suggestion for horizontal adjustment
              c2 = tvar2 & 0xff
              c2 <<= 16
              ts(sct,TUPLE) |= c2           /* horizontal adjustment
              goto EBL
            end
            if tvar2 & 0xff00 = 0x0600      /* print suggestion for vertical adjustment
              c2 = tvar2 & 0xff
              c2 <<= 24
              ts(sct,TUPLE) |= c2           /* vertical adjustment
              goto EBL
            end
                  End of 11/05/05 Code

          end
EBL:
        repeat
        old@n += @n

   ┌────────────────────────────────────────────┐
   │ End of storing original data in set array  │
   └────────────────────────────────────────────┘


          ╔═══════════════════════════════════════════╗
          ║   N E W    S O R T    A L G O R I T H M   ║
          ╚═══════════════════════════════════════════╝

                        09/30/93

    Reorder set array according to location in measure.  Do not
      separate extra chord notes from their original lead notes.
      Do not change the order of bar/clef/grace-note.  Do not
      extract signs, words, or marks when they precede a bar,
      clef or grace note; otherwise extract them and put them
      in front of figures, cues and regular notes.  Do not
      extract time designations when they precede a bar,
      clef or grace note; otherwise extract them and put them
      in front of words, signs, marks, figures, cues and regular
      notes.

    For objects at same location, the order is as follows:

               1. bar, clef, grace note/chord (in original order for each div)
               2.
               3.
               4. change in divisions per quarter
               5. time designation, meter change, key change
               6. word, sign, mark
               7. figure
               8. cue note/chord, cue rest
               9. regular note/chord, regular rest   Note: this is why we send irests
                                                           through the system as rests
                                                           and not as marks
    Summary of algorithm:

       1. For each division, assign parameters as listed above
       2. bar, clef, and grace note/chord will be assigned numbers
            1, 2, and 3 in the order in which they first occur
            in the array on this division
       3. For time designations, words, signs and marks, if
            they preceed a type 1,2,or 3, or if they preceed
            another or this kind which preceeds a 1,2 or 3,
            then they take this respective type
       4. order the elments of mf(.) on each division according
            to the parameter numbers assigned to them.  mf(.)
            will now contain the indexes for the proper order
            of ts(.) from oldsct to sct.
       5. reorder the elements of ts(.) accordingly


        a7 = 0                  /* global counter in measure

        a3 = ts(sct,DIV)        /* divisions per measure
        loop for a2 = 1 to a3
          temp = "999888007066606545"   /* initial "priority" string (with unknowns = 0)
          a6 = 0
          a8 = a7                       /* local counter on this division
          loop for a1 = oldsct + 1 to sct
            if ts(a1,DIV) = a2
              a4 = ts(a1,TYPE)
              a5 = int(temp{a4})
              if a5 = 0         /* setting "unknowns" in the order they are encountered
                ++a6
                if a4 = 7 or a4 = 8
                  temp{7} = chs(a6)
                  temp{8} = chs(a6)
                else
                  temp{a4} = chs(a6)
                end
                a5 = a6
              end
              ts(a1,SORTPAR1) = a5
              ++a8
              mf(a8) = a1
            end
          repeat

          a5 = 20
          loop for a3 = a8 to a7 + 1 step -1
            a1 = mf(a3)
            a4 = ts(a1,SORTPAR1)
            if a4 = 6         /* time designation,  word, sign, mark
              if a5 < 4       /* bar, clef, grace note/chord  or  ...
                ts(a1,SORTPAR1) = a5
                a4 = a5
              else
                if ts(a1,TYPE) = DESIGNATION
                  ts(a1,SORTPAR1) = 5
                end
              end
            end
            a5 = a4
          repeat


        Sort this section of mf(.) according to SORTPAR1, taking care
          not to separate chord tones from their principal tones.


          if a8 > a7 + 1

    /* (1) transfer relevant portion to mf2 array

            loop for a3 = a7+1 to a8
              mf2(a3) = mf(a3)
            repeat

    /* (2) move elements back using order of sort priorites only

            a6 = a7
            loop for a1 = 1 to 9             /* sort priorities
              loop for a3 = a7+1 to a8
                a5 = mf2(a3)                 /* a5 is a ts(.) index
                if a5 <> 1000
                  a5 = ts(a5,SORTPAR1)       /* a5 is a sort priority (0 to 9)
                  if a5 = a1
                    ++a6
                    mf(a6) = mf2(a3)         /* move element back to mf
                    mf2(a3) = 1000           /* and disqualify this element
                  end
                end
              repeat
            repeat
            if a6 <> a8
              putc Program Error in mf() sort
              stop
            end
          end

        End of mf() section sort

          a7 = a8
        repeat

     /* now sort the ts(.,.) array according to the mf(.) order

        loop for a2 = 1 to a8
          putc ~mf(a2)
        repeat

        a5 = sct + 1            /* address of "hole"
        a1 = oldsct + 1
        loop for a2 = 1 to a8
          a3 = mf(a2)
          if a3 <> a1
      /* move ts(a1) to "hole" and  put  ts(a3) in a1 slot
            loop for a6 = 1 to TS_SIZE
              ts(a5,a6) = ts(a1,a6)
              ts(a1,a6) = ts(a3,a6)
            repeat
      /* search mf(.) array for reference to a1 element
      /*   and tell it that this element is now in a5
            loop for a7 = a2+1 to a8
              if mf(a7) = a1
                mf(a7) = a5
                a7 = a8
              end
            repeat
            mf(a2) = a1
      /* set a5 to the new "hole", which is a3
            a5 = a3
          end
      /* advance the destination, a1
          ++a1
        repeat

     Code added 01/07/06 reporting on a possible failure condition
            brought on by a faulty stage2 file.

        a5 = sct - oldsct

        if a5 <> a8
          if a5 > sct
            dputc I think there is a bug here.  If strange things
            putc           happen, look here first.
          else
            putc WARNING! There may be a format error in your stage2 file.
            putc            (possibly having to do with (cue note) durations)
            putc          type <Enter> to proceed on a probationary basis.
            getc
            sct = a8 - oldsct
          end
        end



     Clear work space

        loop for a1 = oldsct + 1 to sct
          ts(a1,SORTPAR1) = 0
        repeat
        loop for a1 = 1 to TS_SIZE
          ts(sct+1,a1) = 0
        repeat

        goto TS_SORTED


         ╔══════════════════════════════════════════╗
         ║  O L D    S O R T    A L G O R I T H M   ║
         ╚══════════════════════════════════════════╝

    Reorder set array according to location in measure.  Do not
      separate extra chord notes from their original lead notes.
      Do not change the order of bar/clef/grace-note.  Do not
      extract signs, words, or marks when they precede a bar,
      clef or grace note; otherwise extract them and put them
      in front of figures, cues and regular notes.

    For objects at same location, the order is as follows:

               1. bar, clef, grace note/chord
               2. change in divisions per quarter
               3. time designation, meter change, key change
               4. word, sign, mark
               5. figure
               6. cue note/chord
               7. cue rest
               8. regular note/chord
               9. regular rest

    Designations have a certain amount of "glue".  If they preceed
      a clef change, they want to keep that position.  If they
      preceed grace notes, they want to stay there also.  If they
      preceed a bar line, they want to stay there.  Otherwise
      they get moved in front of everything except changes in divspq


    Because the position of words, signs, and marks depends on what
      follows, we must assign order priorities starting at the
      bottom of the array.


TS_SORTED:


    Reorder multiple grace notes

        loop for a3 = 1 to MAX_PASS
          passpar(a3) = 200           /* reverse order scheme, starting at 200
        repeat
        a6 = 200
        a5 = 0
        loop for a1 = sct to oldsct step -1
          if a1 > oldsct and chr(ts(a1,TYPE)) in [GR_NOTE,XGR_NOTE]
            if a5 = 0
              a5 = a1
            end
            a2 = ts(a1,PASSNUM)
            ts(a1,SORTPAR1) = passpar(a2)
            if a6 > passpar(a2)
              a6 = passpar(a2)
            end
            if ts(a1,TYPE) = GR_NOTE
              --passpar(a2)
            end
          else
            if a5 > 0           /* some grace notes were found
              a5 -= a1          /* a5 = number of elements
              a4 = 0
              loop for a7 = a6 to 200
                a3 = 0
                loop for a8 = 1 to a5
                  if ts(a1+a8,SORTPAR1) = a7
                    ++a4
                    mf(a4) = a1 + a8
                /* here is where we must add space parameter for GRACE notes
                    if a3 = 0
                      if ts(a1+a8,BEAM_FLAG) = NO_BEAM
                        ts(a1+a8,SPACING) = hpar(97)   /*  Removed  * 4 / 3 05-15-95
                      else
                        ts(a1+a8,SPACING) = hpar(97)
                      end
                      a3 = 1
                    else
                      ts(a1+a8,SPACING) = 0
                    end
                  end
                repeat
              repeat
           /* mf(.) now contains the locations of array elements (in reordered form)

              loop for a8 = 1 to a5
                a4 = mf(a8)
                if a1+a8 <> a4        /* what's there now  is not  what goes there
                  loop for a7 = 1 to TS_SIZE
                    ts(sct+1,a7) = ts(a1+a8,a7)     /* make hole for new element
                    ts(a1+a8,a7) = ts(a4,a7)        /* move in new element
                    ts(a4,a7)    = ts(sct+1,a7)     /* put old element in vacancy
                  repeat
                  loop for a7 = 1 to a5
                    if mf(a7) = a1 + a8             /* this element has been moved
                      mf(a7) = a4                   /*   now give new location
                      a7 = a5
                    end
                  repeat
                  mf(a8) = a1 + a8
                end
              repeat

           /* re-initialize sorting parameters
              loop for a3 = 1 to MAX_PASS
                passpar(a3) = 200
              repeat
              a5 = 0
              a6 = 200
            end
          end
        repeat
        loop for a1 = oldsct+1 to sct
          ts(a1,SORTPAR1) = 0
        repeat

  ┌─────────────────────────┐
  │ End of reorder process. │
  └─────────────────────────┘


        Check for isolated SIGNS, WORDS, or MARKS

        a2 = oldsct + 1
        a5 = ts(a2,DIV)
        loop for a1 = oldsct+1 to sct
          if ts(a1,DIV) <> a5
            loop for a3 = a2 to a1 - 1
              nodtype = ts(a3,TYPE)
              if chr(nodtype) not_in [SIGN,WORDS,MARK]
                a3 = 1000000
              end
            repeat
            if a3 <> 1000000
              loop for a3 = a2 to a1 - 1
                ts(a3,ISOLATED) = 1
              repeat
            end
            a2 = a1
            a5 = ts(a2,DIV)
          end
        repeat

   ┌────────────────────────────────────────────────────────────────┐
   │ Before decoding the notes, we must determine if this part      │
   │ represents more than one independent instrument.  If so then   │
   │ the rules regarding accidentals are slightly different.  Each  │
   │ instrumental part must have its own, independent measax array. │
   └────────────────────────────────────────────────────────────────┘



     For the case where more than one independent instrument is being
     represented on this measure, (vflag > 1) we need to catagorize
     the measure into one of three types:

     (1) one pass, no chords.

        This situation arrises when we have an a2 (zu 2) situation,
        i.e., all instruments are active, but are playing the same
        music, or a 1. (2. or 3.) situation, i.e., only one
        instrument is specifically active -- all other instruments
        have been told not to play.  In this case, the music is
        easy to typeset.

     (2) one pass, chords.

        This is the situation more than 90% of the time.  Two or
        more parts (99.99% of the time, it is two parts) are
        represented in the measure, and the following conditions
        hold true:

           a) all parts have the same rhythm (including resting
                at the same time)
           b) part 1 is at unison or is higher than part 2, etc.

           c) all parts have identical slurs and articulations.
                This includes slurs entering and leaving the
                measure.

           d) if there is a unison and it is an eighth note or less,
                then it is not attached to a beam.

        The parts will be printed as chords.  Slurs and articulations
        will be attached to the note head at the end of stem.  Unison
        notes (represented as chords with two or more identical notes)
        will be printed in one of two ways:

           a) whole notes and larger will be printed side-by-side.

           b) half notes and smaller will be printed with two stems
                (up and down) regardless of the listed stem direction.
                (three unisons cannot be handled by this program)

        With this type, each part (defined by its position in the chord)
        will have its own measax array.  This is because accidentals
        must be repeated, if they appear in different parts.

     (3) more than one pass.

        With this type, notes occuring on the same division and having
        the same duration and same stem direction will be combined into
        one chord.  As with type (2) above, each part (defined in this
        case by pass number) will have its own measax array.  Accidentals
        must be repeated, if they appear in different parts.  Unison
        whole notes and larger will be printed side-by-side.

        if vflag > 1
          if passnum = 1
 
          Must determine if there are chords in this measure

            mcat = 1
            loop for a1 = 1 to sct
              if ts(a1,TYPE) = XNOTE
                mcat = 2
                a1 = sct
              end
            repeat
          else
            mcat = 3
          end
        else
          mcat = 0
        end

    (added 10-12-96)

    Determine links between tie terminators and earlier pitches

        Basically, we look backward through the data to find the pitch
        referred to by the tie terminator.  If the pitch cannot be found,
        this is an error condition.  We must search on the correct staff
        number.  Once we have found the pitch, we need to store its
        index number.  Later we will determine the STAFFLOC parameter.
        This will be used later to generate the mark object and the tie
        super object.

        loop for a1 = oldsct+1 to sct
          if ts(a1,TYPE) = SIGN and ts(a1,SIGN_TYPE) = TIE_TERM
            tsdata(ts(a1,TEXT_INDEX)) = tsdata(ts(a1,TEXT_INDEX)) // pad(4)
            note = tsdata(ts(a1,TEXT_INDEX)){1,4}
            loop for t7 = a1 to oldsct+1 step -1
              if ts(t7,TYPE) <= NOTE_OR_REST
                if ts(t7,STAFF_NUM) = ts(a1,STAFF_NUM)
                  t8 = ts(t7,4)                /* "4" is a cluge, here (see below)
                  if note = tcode(t8)
                    ts(a1,BACKTIE) = t7        /* store ts index of pitch generating tie
                    goto TIE_TERM_FOUND
                  end
                end
              end
            repeat
            return 10
          end
TIE_TERM_FOUND:
        repeat

    End of 10-12-96 addition



    Decode pitches, store unmodified accidentals in ts(.,AX)

        loop for a1 = oldsct+1 to sct
          nodtype = ts(a1,TYPE)
          if nodtype <= NOTE_OR_REST
            a2 = ts(a1,4)
            note = tcode(a2)
            perform decodenote
            if @c = 100
              @c += ts(a1,CLAVE)       /* see "floating rest flag"
            end
            ts(a1,CLAVE) = @c          /* Here is where CLAVE is definitively set
            ts(a1,AX) = @d
            a4 = ts(a1,STAFF_NUM) + 1
            if @c < 100
              ts(a1,STAFFLOC) = 52 - @c - cline(a4) + c8flag(a4) * notesize / 2
              ts(a1,STAFFLOC) = 52 - @c - cline(a4) + c8flag(a4) + 20 * notesize / 2 - vpar20
            end

       We need to capture the note shape data now, because it will figure in on
       whether a passage is iso-rhythmic; i.e., you can't have iso-rhythm with
       different note shapes.    Code added 02/19/06

            a14 = ts(a1,TSR_POINT)
            a4 = ors(tsr(a14){1})
            if a4 > 16
              a4 >>= 4           /* upper for bits
              a4 <<= 20          /*   shifted to space 20-23
              ts(a1,SUBFLAG_1) |= a4
            end

          end
          if chr(nodtype) in [SIGN,WORDS,MARK]
            a4 = ts(a1,STAFF_NUM) + 1    /* staff number
            a2 = ts(a1,SUPER_TYPE) + 1 / 2
            if chr(a2) in [OCT_UP,OCT_DOWN,DBL_OCT_UP,DBL_OCT_DOWN]

          adjust c8flag(.)

              if a2 = OCT_UP
                c8flag(a4) = -7
              end
              if a2 = OCT_DOWN
                c8flag(a4) = 7
              end
              if a2 = DBL_OCT_UP
                c8flag(a4) = -14
              end
              if a2 = DBL_OCT_DOWN
                c8flag(a4) = 14
              end
              transflag(a4) = 2 * a2
            end
            if ts(a1,SUPER_TYPE) = NORMAL_TRANS
              c8flag(a4) = 0             /* return to normal
              if transflag(a4) < 2 * OCT_UP
                putc Possible Coding error with transpositions
                putc Type <Return> to continue
                getc
              end
              ts(a1,SUPER_TYPE) = transflag(a4)
              transflag(a4) = 0
            end
          end
          if nodtype = CLEF_CHG
            a4 = ts(a1,STAFF_NUM) + 1    /* staff number
            clef(a4) = ts(a1,CLEF_NUM)
            perform zjcline (a4)
*     this resets clef and cline

    /*      ts(a1,CLEF_FONT) += z    Unnecessary and, in fact, an error! 

            ts(a1,TRANS_FLAG) = k                          /* 
            ts(a1,CLEF_STAFF_POS) = 5 - j * notesize       /*   Possibly
            a3 = hpar(8) * 5 / 6                           /*   unnecessary
            if ts(a1,CLEF_FONT) >= 128   /* music font     /*   at this
              a3 = a3 * 8 / 10                             /*   point
            end                                            /* 
            ts(a1,SPACING) = a3                            /* 

          end
        repeat


    If mcat = 3, reorganize notes on the same division.  If two notes
    with different pass numbers have the same duration and stem directions
    in the same direction, and these notes do not have beam connections,
    then these notes can be combined into one chord.  This will save
    considerable trouble later during the computing of x-offsets (both
    local and global) and the setting of stems.

    09/22/93  Actually I would like to expand this section.

     (1) I would like to try to combine isorhythmic passages that do connect
         to beams

     (2) If the entire measure is isorhythmic, then I would like to set
         mcat to 2 and reduce the number of passes

     (3) Also, if the measure is isorhythmic, I would like to print out
         rests only one time

     (4) Also, if mcat > 1, accidentals on the same line should NOT be
         reprinted.  This should be easy to fix, simply by looping though
         all simultanities on a staff and removing accidentals that
         occur twice on the same pitch.

    available variables: a1 --> a16

        if mcat = 3               /* %%% add code here for changing ax behavior

      First thing: fix accidentals according to pass number

          loop for a1 = oldsct+1 to sct
            nodtype = ts(a1,TYPE)
            if nodtype <= NOTE_OR_REST
              a4 = ts(a1,PASSNUM)
              if a4 > 3
                putc This code will not work with more than 3 passes
                examine
                stop
              end
              perform decodeax (a1,a4)
            end
            if nodtype = BAR_LINE
              loop for a3 = 1 to 50
                loop for a4 = 1 to 4                    /* 06/04/08 was 3
                  measax(a4,a3) = claveax(a3)
                  measax(a4,a3) = tclaveax(a3)          /* New 12/14/07
                repeat
              repeat
            end
            if nodtype = CLEF_CHG
              a4 = ts(a1,STAFF_NUM) + 1    /* staff number
              clef(a4) = ts(a1,CLEF_NUM)
              perform zjcline (a4)
*     this resets clef and cline
              ts(a1,CLEF_FONT) += z        /* music font
              ts(a1,TRANS_FLAG) = k
              ts(a1,CLEF_STAFF_POS) = 5 - j * notesize
              a3 = hpar(8) * 5 / 6                           /* Added 06-24-94
              if ts(a1,CLEF_FONT) > 128     /* music font
                a3 = a3 * 8 / 10
              end
              ts(a1,SPACING) = a3
              if nstaves > 1     /* Case: assume one part to stave (usual case)
                loop for a3 = 1 to 50
                  measax(a4,a3) = claveax(a3)
                  measax(a4,a3) = tclaveax(a3)          /* New 12/14/07
                repeat
              else
                loop for a4 = 1 to 4                    /* 06/04/08 was 3
                  loop for a3 = 1 to 50
                    measax(a4,a3) = claveax(a3)
                    measax(a4,a3) = tclaveax(a3)        /* New 12/14/07
                  repeat
                repeat
              end
            end
          repeat


      Now you can combine notes into chords  (and alter pass numbers)



      If there are notes of different note shapes in a measure, this is a
      non-starter for combining any notes into chords.  All notes must have
      the same note shape (bits 20-23 of SUBFLAG_1).  This information was
      encoded at the same time as pitch.  (added 02/19/06)

          a2 = 0
          loop for a1 = oldsct+1 to sct
            nodtype = ts(a1,TYPE)
            if nodtype <= NOTE_OR_REST
              if a2 = 0
                a2 = a1
              end
              if (ts(a2,SUBFLAG_1) & 0xf00000) <> (ts(a1,SUBFLAG_1) & 0xf00000)
                goto ISO_DONE
              end
            end
          repeat



      First check to see if the entire measure is isorhythmic.  This will
      save time in the end, and is also necessary in determining whether or
      not to eliminate duplicate rests.  There are some caviats here:

       (1) Notes with lower pass numbers must always be unison or higher
             on the staff
       (2) All stem directions must be the same (for a particular division)
             REMOVED

       (3) All beam flags for notes from each pass must be identical.

       (4) Every division must have a representative from each pass.  These
             must be either all notes or all rests.

          /* %%% add code here for disabling isorhythmic compression

          loop for a1 = oldsct+1 to sct
            nodtype = ts(a1,TYPE)
            if nodtype <= NOTE_OR_REST
              loop for a2 = a1 + 1 to sct
                if ts(a2,DIV) <> ts(a1,DIV) or ts(a2,SPACING) <> 0
                  goto JOL1
                end
                if nodtype = REST or nodtype = CUE_REST
                  if ts(a2,TYPE) <> nodtype
                    goto JOL1
                  end
                else
                  if ts(a2,TYPE) <> nodtype and ts(a2,TYPE) <> nodtype + 1
                    goto JOL1
                  end
                end
              repeat
JOL1:
              --a2
              if a2 - a1 + 1 < passnum
                goto ISO_FAIL
              end
              a4 = 0
              a5 = 0
              a6 = ts(a1,PASSNUM)
              a7 = 1000
              loop for a3 = a1 to a2
                if ts(a3,CLAVE) < 100
                  if ts(a3,STAFF_NUM) <> ts(a1,STAFF_NUM)
                    goto ISO_FAIL
                  end
                  if bit(1,ts(a3,STEM_FLAGS)) <> bit(1,ts(a1,STEM_FLAGS))
                    goto ISO_FAIL
                  end
                  if ts(a3,BEAM_FLAG) <> ts(a1,BEAM_FLAG)
                    goto ISO_FAIL
                  end
                  if bit(0,ts(a3,SUPER_FLAG)) <> bit(0,ts(a1,SUPER_FLAG))    /* ties
                    goto ISO_FAIL
                  end
                  if bit(2,ts(a3,STEM_FLAGS)) = 0         /* number of "events"
                    ++a4
                  end
                  if ts(a3,PASSNUM) = a6                 /* order of pitches */
                    if ts(a3,CLAVE) < a7
                      a7 = ts(a3,CLAVE)
                    end
                  else
                    if ts(a3,CLAVE) > a7
                      goto ISO_FAIL
                    end
                    a6 = ts(a3,PASSNUM)
                    a7 = ts(a3,CLAVE)
                  end
                else
                  ++a5
                end
              repeat
              if a4 = 0
                if a5 <> passnum
                  goto ISO_FAIL
                end
              else
                if a4 <> passnum or a5 > 0
                  goto ISO_FAIL
                end
              end
              a1 = a2
            end
          repeat


      The measure meets the conditions of isorhythmic compression.  Here is
      what we must do:

        (1) Rests:  Delete duplicate rests.  Do this all at one time,
              since this involves resizing the ts array.

            Note on this: I don't think autoscr actually wants to delete
              rests, but rather to make them "silent."  To do otherwise
              might remove time from a track.

        (2) Notes--situation 1: Note not connected to a beam

           New condition 12/20/05: If stem_change_flag < 3, then do the
             steps below only if the stem directions are the same.

             If no unison and no chords in separate parts, then combine all
                  pitches into one chord
               If separate stem directions do not agree, determine
                 best direction; otherwise use common direction
           
                      TYPE: for each note group, make first type 1,4,7 and
                              all others 2,5,8
                STEM_FLAGS: set all bit2's; set all bit3's for all but first
                              member of group
                 BEAM_FLAG: zero for all but first member of chord group
                 BEAM_CODE: zero for all but first member of chord group
                 PASSNUM: equal to PASSNUM for first member of group
           
             Otherwise, set the stem direction for the upper pass
               to up and for the lower pass to down.

        (3) Notes--situation 2: Note is connected to a beam

             For all notes on that beam determine if there are any unisons
                or any chords in separate chords.

               If no unisons and no chords, then combine all pitches into one chord
                 If separate stem directions do not agree, determine
                   best direction; otherwise use common direction

                        TYPE: for each note group, make first type 1,4,7 and
                                all others 2,5,8
                  STEM_FLAGS: set all bit2's; set all bit3's for all but first
                                member of group
                   BEAM_FLAG: zero for all but first member of chord group
                   BEAM_CODE: zero for all but first member of chord group
                   PASSNUM: equal to PASSNUM for first member of group

               If unisons, then set the stem direction for the upper pass
                 to up and for the lower pass to down.

        (4) If all notes in measure were combined into chords, then
               decrease passnum by amount of largest PASSNUM + 1 / 2



    (1) Rests:  Delete duplicate rests


          a1 = oldsct+1
COMPRESS1:
          nodtype = ts(a1,TYPE)
          if (nodtype = REST or nodtype = CUE_REST) and rest_collapse = TRUE
            loop for a2 = a1 + 1 to sct
              if ts(a2,DIV) <> ts(a1,DIV) or ts(a2,TYPE) <> nodtype
                goto JOL2
              end
            repeat
JOL2:
#if AUTOSCR

      This section of code different from AUTOSET
 
            if a2 > a1 + 1                           /* a2 points beyond last dup. rest
              if nodtype = CUE_REST
                a5 = a1 + 1
                loop for a3 = a2 to sct
                  loop for a4 = 1 to TS_SIZE
                    ts(a5,a4) = ts(a3,a4)
                  repeat
                  ++a5
                repeat
                loop for a4 = 1 to TS_SIZE          /* 1/30/96  clear last ts(.,.) line
                  ts(sct,a4) = 0
                repeat
                sct -= a2 - a1 - 1
              else
                loop for a4 = a1 + 1 to a2 - 1
                  if chr(ts(a4,CLAVE)) in [100,101,200]
                    ts(a4,CLAVE) = 200
                    ts(a4,PASSNUM) = ts(a1,PASSNUM)    /* I hope this works ????
                  else
                    dputc Program Error:  rest found whose CLAVE was improperly set.
                    stop
                  end
                repeat
                a1 += (a2 - a1 - 1)                 /* move a1 to last dup. rest
              end
            end

#else

      This section of code different from AUTOSCR
 
            if a2 > a1 + 1                           /* do this only if another rest is found
              a5 = a1 + 1
              loop for a3 = a2 to sct
                loop for a4 = 1 to TS_SIZE
                  ts(a5,a4) = ts(a3,a4)
                repeat
                ++a5
              repeat
              loop for a4 = 1 to TS_SIZE            /* 1/30/96  clear last ts(.,.) line
                ts(sct,a4) = 0
              repeat
              sct -= a2 - a1 - 1
            end

#endif
          end
          ++a1
          if a1 <= sct
            goto COMPRESS1
          end

    (2) (3) Notes-- situations 1 and 2

          a16 = 0  /* New 12/20/05 and be careful not to modify this in other parts of AUTOSET
          a15 = 0  /* New 12/20/05
          a10 = 0
          a5 = 0
          a6 = 0
          a7 = 0
          a8 = 0

          loop for a1 = oldsct+1 to sct
            nodtype = ts(a1,TYPE)
            if nodtype = NOTE or nodtype = CUE_NOTE or nodtype = GR_NOTE
              loop for a2 = a1 + 1 to sct
                if ts(a2,DIV) <> ts(a1,DIV) or ts(a2,SPACING) <> 0
                  goto JOL3
                end
              repeat while ts(a2,TYPE) = nodtype or ts(a2,TYPE) = nodtype + 1
JOL3:
              --a2

      Move all dynamics for notes on same division to first note (because it is easy
          to do at this point)    (12/20/05 moving this code inside processing loop)

              a4 = 0
              a7 = 0                               /* New 05/17/03
              loop for a3 = a1 to a2
                a4 |= ts(a3,SUBFLAG_1) & 0x3c00    /* 0000 0000 0011 1100 0000 0000
                ts(a3,SUBFLAG_1) &= 0xffc3ff       /* 1111 1111 1100 0011 1111 1111
                a7 |= ts(a3,ED_SUBFLAG_1) & 0x3c00 /* 0000 0000 0011 1100 0000 0000 05/17/03
                ts(a3,ED_SUBFLAG_1) &= 0xffc3ff    /* 1111 1111 1100 0011 1111 1111 05/17/03
              repeat
              ts(a1,SUBFLAG_1) |= a4
              ts(a1,ED_SUBFLAG_1) |= a7            /* New 05/17/03

      Remove duplicate fermatas for notes on same division (because it is easy
          to do at this point)

              a4 = ts(a1,SUBFLAG_1) & 0x0080       /* 0000 0000 0000 0000 1000 0000
              a7 = ts(a1,ED_SUBFLAG_1) & 0x0080    /* 0000 0000 0000 0000 1000 0000 05/17/03
              loop for a3 = a1 + 1 to a2
                if ts(a3,SUBFLAG_1) & 0x0080 = a4

/*  1 1111 1111 1111 1111 1111 0111 1111   "1 1111 " added 04/22/08 and 10/08/08
                  ts(a3,SUBFLAG_1) &= 0x1fffff7f
                end
                if ts(a3,ED_SUBFLAG_1) & 0x0080 = a7   /* New 05/17/03

/*  1 1111 1111 1111 1111 1111 0111 1111   "1 1111 " added 04/22/08 and 10/08/08
                  ts(a3,ED_SUBFLAG_1) &= 0x1fffff7f
                end
              repeat
              if a2 - a1 + 1 > passnum
                a7 = 1                      /* chords are present on this division
              end

      Determine if there is a unison in this group

              if a7 = 0
              if a7 = 0 and stem_change_flag = 3      /* New condition 12/20/05
                loop for a3 = a1 + 1 to a2
                  if ts(a3,CLAVE) = ts(a3-1,CLAVE)
                    a7 = 1
                  end
                repeat
              end

              if a16 = 0
                loop for a3 = a1 + 1 to a2
                  if bit(1,ts(a3,STEM_FLAGS)) <> bit(1,ts(a1,STEM_FLAGS))
                    a8 = 1                  /* conflicting stem directions
                  end
                repeat
              end
              if ts(a1,BEAM_FLAG) <> 0      /* this note is on a beam
                a15 = 1                     /* New 12/20/05 "beam flag"
                if ts(a1,BEAM_FLAG) = START_BEAM
                  a16 = a1                  /* index starts (first/top) beam
                end
                if ts(a1,BEAM_FLAG) = END_BEAM
                  a16 += INT10000           /* beams end; now use saved value of a1 from above
                end
              else
                a16 = a1 + INT10000         /* "no beam" case
              end
              if a16 > INT10000             /* process notes here
                a16 -= INT10000             /* recover value of starting "a1"

            New condition 12/20/05: If stem_change_flag < 3, then (for
              non-beam case) do steps below only if the stem directions
              are the same.  (i.e., when a15 = 0, a8 must be zero,
              if stem_change_flag < 3)

                if a15 = 0      /* no beam
                  if stem_change_flag < 3 and a8 = 1
                    a10 = 1                            /* New condition 12/20/05
                    goto NO_STEM_CHANGE
                  end
                end

            At this point: either a15 = 1 (this is a beamed group or set of beamed groups)
                  or stem_change_flag = 3 (old code situation)
                                or a8 = 0 (all stems point the same way)



       Case 1: either a unison between passes or a chord on one of the passes
               (note: in order for a unison to trigger this case, stem_change_flag must = 3
                      otherwise, unisons will fall into case 2

                if a7 = 1

         New 12/20/05 change stem directions only of stem_change_flag = 3

                  if stem_change_flag = 3
                    loop for a3 = a16 to a2                /* all notes inclusive
                      a7 = ts(a3,TYPE)
                      if a7 <= NOTE_OR_REST and a7 <> REST and a7 <> CUE_REST
                        if ts(a3,PASSNUM) = ts(a16,PASSNUM)
                          ts(a3,STEM_FLAGS) &= 0xfffd      /* stem up for upper pass
                        else
                          ts(a3,STEM_FLAGS) |= 0x0002      /* stem down for lower pass
                        end
                      end
                    repeat
                  end
                  a10 = 1
                else

       Old Case 2: no unisons, no chords -- combine passes in one chord
                     (and stem_change_flag = 3)

       12/20/05 Case 2: no chords -- combine passes in one chord
                        (note: unisons may fall into this case if stem_change_flag < 3)


                  if a8 = 1 and stem_change_flag < 3     /* New condition 12/20/05
                    a10 = 1
                    goto NO_STEM_CHANGE
                  end

                  if a8 = 1            /* determine stem direction
                    a8 = 0
                    loop for a3 = a16 to a2
                      a7 = ts(a3,TYPE)
                      if a7 <= NOTE_OR_REST and a7 <> REST and a7 <> CUE_REST
                        a8 += ts(a3,STAFFLOC)
                      end
                    repeat
                    a8 <<= 1
                    a8 /= notesize
                    a9 = a2 - a16 + 1
                    a8 += a9 + 1 / 2
                    a8 /= a9
                    if a8 >= 5
                      a9 = UP
                    else
                      a9 = DOWN
                    end
                  else
                    a9 = bit(1,ts(a16,STEM_FLAGS))
                  end

                  a11 = 0
                  a12 = 0
                  loop for a3 = a16 to a2       /* put all notes into chords
                    a7 = ts(a3,TYPE)
                    if a7 <= NOTE_OR_REST and a7 <> REST and a7 <> CUE_REST
                      ts(a3,STEM_FLAGS) &= 0xfffd     /* prepare for new stem direction
                      ts(a3,STEM_FLAGS) |= a9 << 1

      Also move all dynamics for notes on same division to first note (This is correct place
        to do this operation 12/20/05)   This code uses a4, a6 and a14 in a temporary manner

                      if ts(a3,DIV) <> a11 or ts(a3,SPACING) <> 0 or a12 <> a7 or a3 = a16
                        a12 = a7
                        a11 = ts(a3,DIV)
                        ts(a3,STEM_FLAGS) |= 0x04
                        a8 = a3

      Collect dynamics data for this note (a3) 12/20/05


/*  1 1100 0000 0000 0011 1100 0000 0000  "1 1100 " added 10/08/08
                        a4 = ts(a3,SUBFLAG_1)    & 0x1c003c00

/*  1 1100 0000 0000 0011 1100 0000 0000  "1 1100 " added 10/08/08
                        a6 = ts(a3,ED_SUBFLAG_1) & 0x1c003c00
                      else
                        ts(a3,TYPE) = ts(a8,TYPE) + 1
                        ts(a3,STEM_FLAGS) |= 0x0c
                        ts(a3,BEAM_FLAG) = 0
                        ts(a3,BEAM_CODE) = 0
                        if ts(a3,PASSNUM) > a5
                          a5 = ts(a3,PASSNUM)         /* save max passnum
                        end
                        ts(a3,PASSNUM) = ts(a8,PASSNUM)

      Merge dynamics data with data for first (a8) note


/*  1 1100 0000 0000 0011 1100 0000 0000  "1 1100 " added 10/08/08
                        a4 |= ts(a3,SUBFLAG_1)    & 0x1c003c00

/*  1 1100 0000 0000 0011 1100 0000 0000  "1 1100 " added 10/08/08
                        a6 |= ts(a3,ED_SUBFLAG_1) & 0x1c003c00

      Turn off dynamics data for this note (a3)


/* 0 0011 1111 1111 1100 0011 1111 1111  "0 0011 " added 04/22/08 and 10/08/08
                        ts(a3,SUBFLAG_1) &= 0x1fffc3ff

/* 0 0011 1111 1111 1100 0011 1111 1111  "0 0011 " added 04/22/08 and 10/08/08
                        ts(a3,ED_SUBFLAG_1) &= 0x1fffc3ff

      Add in (new) dynamics data to first (a8) note

                        ts(a8,SUBFLAG_1) |= a4
                        ts(a8,ED_SUBFLAG_1) |= a6

           The following code is untested, and may cause problems.
           Note: 10/28/07 it has!   I will make some changes that fix a definite
             bug, but there may still be other problems.

                        a14 = ts(a3,TSR_POINT)             /* combine tsr strings
                        tbit2 = cbi(tsr(a14))
                        a14 = ts(a8,TSR_POINT)
                        tbit1 = cbi(tsr(a14))
                        tbit1 = bor(tbit1,tbit2)
                        tsr(a14) = cby(tbit1)

                        c4 = ts(a3,TSR_POINT)
                        c5 = ts(a8,TSR_POINT)
             /* byte 1
                        c6 = ors(tsr(c4){1}) & 0xff
                        c7 = ors(tsr(c5){1}) & 0xff
                        c7 |= c6
                        tsr(c5){1} = chr(c7)
             /* byte 2
                        c6 = ors(tsr(c4){2}) & 0xff
                        c7 = ors(tsr(c5){2}) & 0xff
                        c7 |= c6
                        tsr(c5){2} = chr(c7)
             /* byte 3 = x offset (modification by suggestion)
                        c6 = ors(tsr(c4){3}) & 0xff
                        c7 = ors(tsr(c5){3}) & 0xff
                        if c6 <> c7
                          putc WARNING at approximate measure number ~(measnum - 1)
                          putc
                          putc       You have asked autoset/scr to combine into a chord two
                          putc   pitches which have different x offsets.  This will be done, but
                          putc   the results are unpredictable.  Note combination usually arrises
                          putc   when two instruments occupy the same staff (multi track) and have
                          putc   simultaneous notes with the same stem direction.  If you really
                          putc   want different x offsets, you should make the stem directions on
                          putc   these notes different.
                          putc
                        end
                        tsr(c5){3} = chr(c7)
             /* byte 4 = y offset (modification by suggestion)
                        c6 = ors(tsr(c4){4}) & 0xff
                        c7 = ors(tsr(c5){4}) & 0xff
                        if c6 <> c7
                          putc WARNING at approximate measure number ~(measnum - 1)
                          putc
                          putc       You have asked autoset/scr to combine into a chord two
                          putc   pitches which have different y offsets.  This will be done, but
                          putc   the results are unpredictable.  Note combination usually arrises
                          putc   when two instruments occupy the same staff (multi track) and have
                          putc   simultaneous notes with the same stem direction.  If you really
                          putc   want different x offsets, you should make the stem directions on
                          putc   these notes different.
                          putc
                        end
                        tsr(c5){4} = chr(c7)

                        c7 = TSR_LENG
                        a14 = ts(a3,TSR_POINT)             /* combine tsr strings
                        tbit2 = cbi(tsr(a14){5..})
                        a14 = ts(a8,TSR_POINT)
                        tbit1 = cbi(tsr(a14){5..})
                        tbit1 = bor(tbit1,tbit2)
                        tsr(a14){5..c7} = cby(tbit1)

                       End of 10/28/07 modifications


      End of dynamics merge process (moved here 12/20/05)

                      end
                    end
                  repeat

                end
NO_STEM_CHANGE:
                a16 = 0
                a7 = 0
                a8 = 0
                a15 = 0                        /* New 12/20/05
              end
              a1 = a2
            end
          repeat


    (4) If all notes in measure were combined into chords, then
          Adjust PASSNUM for all nodes and decrease passnum by
          amount of largest PASSNUM + 1 / 2  (not fully implemented)

          if a10 = 0
            if a5 > 2
              putc This program may have problems with more than
              putc   two separate instruments on a staff line
            end
            loop for a1 = oldsct+1 to sct
              ts(a1,PASSNUM) = 1
            repeat
            passnum = 1
          end

          goto ISO_DONE

ISO_FAIL:

          loop for a1 = oldsct+1 to sct
            nodtype = ts(a1,TYPE)
            if nodtype <= NOTE_OR_REST and ts(a1,BEAM_FLAG) = NO_BEAM
              a4 = ts(a1,DIV)                /* test note
              a5 = ts(a1,NOTE_DUR)
              a6 = bit(1,ts(a1,STEM_FLAGS))
              a7 = ts(a1,STAFF_NUM)
              if nodtype = NOTE or nodtype = CUE_NOTE
                loop for a3 = a1+1 to sct
                  if ts(a3,DIV) = a4
                    if ts(a3,TYPE) = nodtype and ts(a3,NOTE_DUR) = a5
                      if bit(1,ts(a3,STEM_FLAGS)) = a6 and ts(a3,BEAM_FLAG) = NO_BEAM
                        if ts(a3,STAFF_NUM) = a7

            Move this to be part of a chord on test note

                          a9 = a1+1
                          perform rotate_array (a9,a3)
                          ts(a9,TYPE) = nodtype + 1    /* chord note
                          ts(a9,STEM_FLAGS) |= 0x0c
                          ts(a1,STEM_FLAGS) |= 0x04    /* make note at a1 "first" in chord 1/30/96
                          ts(a9,PASSNUM) = ts(a1,PASSNUM)
                        end
                      end
                    end
                  else
                    a3 = sct
                  end
                repeat
              end
              if nodtype = GR_NOTE
                a8 = ts(a1,NTYPE)
                loop for a3 = a1+1 to sct
                  if ts(a3,DIV) = a4
                    if ts(a3,TYPE) = GR_NOTE and ts(a3,NTYPE) = a8 and ts(a3,SPACING) = 0
                      if bit(1,ts(a3,STEM_FLAGS)) = a6 and ts(a3,BEAM_FLAG) = NO_BEAM
                        if ts(a3,STAFF_NUM) = a7

            Move this to be part of a chord on test note

                          a9 = a1+1
                          perform rotate_array (a9,a3)
                          ts(a9,TYPE) = XGR_NOTE
                          ts(a9,STEM_FLAGS) |= 0x0c
                          ts(a1,STEM_FLAGS) |= 0x04    /* make note at a1 "first" in chord 1/30/96
                          ts(a9,PASSNUM) = ts(a1,PASSNUM)
                        end
                      end
                    end
                  else
                    a3 = sct
                  end
                repeat
              end
            end
          repeat



      New code 10/14/07
      Without wrecking what already works with autoset, I will now attempt to
         combine groups of notes under the same beam for the case where there
         is a third "silent" track or other disruptive objects.

#if AUTOSCR
          loop for a1 = oldsct+1 to sct
            nodtype = ts(a1,TYPE)
            if nodtype = NOTE and ts(a1,BEAM_FLAG) = START_BEAM
              a4 = ts(a1,DIV)                /* test note
              a5 = ts(a1,NOTE_DUR)
              a6 = bit(1,ts(a1,STEM_FLAGS))
              a7 = ts(a1,STAFF_NUM)

          Question 1: Is there another note on this division?

              loop for c1 = a1 + 1 to sct
                if ts(c1,DIV) = a4
                  if ts(c1,TYPE) = NOTE
                    goto BCOMA_1
                  end
                else
                  a1 = c1 - 1
                  goto NO_BCOMA
                end
              repeat
              goto NO_BCOMA
BCOMA_1:

          Question 2: Does this note have the proper characteristics?

              a2 = c1
              if ts(a2,BEAM_FLAG) <> START_BEAM
                goto NO_BCOMA
              end
              if ts(a2,NOTE_DUR) <> a5
                goto NO_BCOMA
              end
              if bit(1,ts(a2,STEM_FLAGS)) <> a6
                goto NO_BCOMA
              end
              if ts(a2,STAFF_NUM) <> a7
                goto NO_BCOMA
              end

          Setup fixup array

              beam_fixup_cnt = 1
              beam_fixup_arr(1,1) = a1
              beam_fixup_arr(1,2) = a2

          Go looking for other note pairs

              c3 = a2
BCOMA_4:
              loop for c1 = c3 + 1 to sct
                if ts(c1,TYPE) = NOTE
                  goto BCOMA_2
                end
              repeat
              goto NO_BCOMA
BCOMA_2:
              loop for c2 = c1 + 1 to sct
                if ts(c2,TYPE) = NOTE
                  goto BCOMA_3
                end
              repeat
              goto NO_BCOMA

          Note pair found; check fit

BCOMA_3:
              if ts(c1,BEAM_FLAG) = CONT_BEAM or ts(c1,BEAM_FLAG) = END_BEAM
                if ts(c2,BEAM_FLAG) <> ts(c1,BEAM_FLAG)
                  goto NO_BCOMA
                end
                if ts(c2,DIV) <> ts(c1,DIV) or ts(c2,NOTE_DUR) <> ts(c1,NOTE_DUR)
                  goto NO_BCOMA
                end
                if bit(1,ts(c1,STEM_FLAGS)) <> a6 or bit(1,ts(c2,STEM_FLAGS)) <> a6
                  goto NO_BCOMA
                end
                if ts(c1,STAFF_NUM) <> a7 or ts(c2,STAFF_NUM) <> a7
                  goto NO_BCOMA
                end

                ++beam_fixup_cnt
                beam_fixup_arr(beam_fixup_cnt,1) = c1
                beam_fixup_arr(beam_fixup_cnt,2) = c2

                if ts(c1,BEAM_FLAG) = CONT_BEAM
                  c3 = c2
                  goto BCOMA_4        /* go look for more pairs
                end
              end

          Now move these notes to be part of chords on test notes

              loop for c3 = 1 to beam_fixup_cnt
                c1 = beam_fixup_arr(c3,1)
                c2 = beam_fixup_arr(c3,2)
                ts(c2,TYPE) = nodtype + 1    /* chord note
                ts(c2,STEM_FLAGS) |= 0x0c
                ts(c1,STEM_FLAGS) |= 0x04
                ts(c2,PASSNUM) = ts(c1,PASSNUM)
                ts(c1,SUBFLAG_1) |= ts(c2,SUBFLAG_1)  /* 02-11-96  move subflags to main note
                ts(c2,SUBFLAG_1) = 0                  /* this may cause problems
                ts(c1,ED_SUBFLAG_1) |= ts(c2,ED_SUBFLAG_1)  /* New 05/17/03
                ts(c2,ED_SUBFLAG_1) = 0
                ts(c1,SUBFLAG_2) |= ts(c2,SUBFLAG_2)        /* New 05/17/03
                ts(c2,SUBFLAG_2) = 0
                ts(c1,ED_SUBFLAG_2) |= ts(c2,ED_SUBFLAG_2)  /* New 05/17/03
                ts(c2,ED_SUBFLAG_2) = 0
              repeat
              a1 = c2
            end
NO_BCOMA:
          repeat

      End of 10/14/07 New code



#else

      New code 1/30/96 to look for cases where groups of notes might be combined
         under the same beam.  At the moment, this works only with two parts and
         with regular notes.

          loop for a1 = oldsct+1 to sct
            nodtype = ts(a1,TYPE)
            if nodtype = NOTE and ts(a1,BEAM_FLAG) = START_BEAM
              a4 = ts(a1,DIV)                /* test note
              a5 = ts(a1,NOTE_DUR)
              a6 = bit(1,ts(a1,STEM_FLAGS))
              a7 = ts(a1,STAFF_NUM)
              a2 = a1 + 1
              if ts(a2,TYPE) = NOTE and ts(a2,BEAM_FLAG) = START_BEAM
                if ts(a2,DIV) = a4 and ts(a2,NOTE_DUR) = a5
                  if bit(1,ts(a2,STEM_FLAGS)) = a6 and ts(a2,STAFF_NUM) = a7
                    c1 = a1 + 2
                    c2 = a2 + 2
                    loop while ts(c1,BEAM_FLAG) = CONT_BEAM or ts(c1,BEAM_FLAG) = END_BEAM
                      if ts(c2,BEAM_FLAG) <> ts(c1,BEAM_FLAG)
                        goto NO_BCOM
                      end
                      if ts(c1,TYPE) <> NOTE or ts(c2,TYPE) <> NOTE
                        goto NO_BCOM
                      end
                      if ts(c2,DIV) <> ts(c1,DIV) or ts(c2,NOTE_DUR) <> ts(c1,NOTE_DUR)
                        goto NO_BCOM
                      end
                      if bit(1,ts(c1,STEM_FLAGS)) <> a6 or bit(1,ts(c2,STEM_FLAGS)) <> a6
                        goto NO_BCOM
                      end
                      if ts(c1,STAFF_NUM) <> a7 or ts(c2,STAFF_NUM) <> a7
                        goto NO_BCOM
                      end
                      c1 += 2
                      c2 += 2
                    repeat
                    c1 -= 2
                    c2 -= 2
                    if ts(c1,BEAM_FLAG) <> END_BEAM or ts(c2,BEAM_FLAG) <> END_BEAM
                      goto NO_BCOM
                    end

            Move these notes to be part of chords on test notes

                    loop for c3 = a1 to c1 step 2
                      a9 = c3 + 1
                      ts(a9,TYPE) = nodtype + 1    /* chord note
                      ts(a9,STEM_FLAGS) |= 0x0c
                      ts(c3,STEM_FLAGS) |= 0x04
                      ts(a9,PASSNUM) = ts(c3,PASSNUM)
                      ts(c3,SUBFLAG_1) |= ts(a9,SUBFLAG_1)  /* 02-11-96  move subflags to main note
                      ts(a9,SUBFLAG_1) = 0                  /* this may cause problems
                      ts(c3,ED_SUBFLAG_1) |= ts(a9,ED_SUBFLAG_1)  /* New 05/17/03
                      ts(a9,ED_SUBFLAG_1) = 0
                      ts(c3,SUBFLAG_2) |= ts(a9,SUBFLAG_2)        /* New 05/17/03
                      ts(a9,SUBFLAG_2) = 0
                      ts(c3,ED_SUBFLAG_2) |= ts(a9,ED_SUBFLAG_2)  /* New 05/17/03
                      ts(a9,ED_SUBFLAG_2) = 0
                    repeat
                    a1 = a9
                  end
                end
              end
            end
NO_BCOM:
          repeat
#endif


      Check to see if the number of passes has been reduced
         (omitted for the moment; may not be necessary)


ISO_DONE:

        end

    Make sure at this point that all chords are oriented with the top
    note first.  Also, for each note (or set of notes = chord), compute
    the position of the note head at the end of the stem, and also
    compute the position of the end of the stem.  Later, we will make
    a "best guess" about what the beam height for those notes belonging
    to a beam.  Store the note position in VIRT_NOTE (for all notes
    of the chord) and the stem position in VIRT_STEM (for all notes
    of the chord)

        loop for a1 = oldsct+1 to sct
          nodtype = ts(a1,TYPE)
          if chr(nodtype) in [NOTE,CUE_NOTE,GR_NOTE]
            if bit(2,ts(a1,STEM_FLAGS)) = 1  /* This is a chord
              a5 = ts(a1,STEM_FLAGS) & 0x03           /* save lower two bits
              a2 = a1 + 1
              loop while ts(a2,TYPE) = nodtype + 1
                ++a2
              repeat
              --a2            /* a2 = last note in chord

          Bubble sort

              loop for a3 = a1 to a2-1
                loop for a4 = a3 to a2
                  if ts(a3,CLAVE) < ts(a4,CLAVE)
                    loop for a7 = 2 to TS_SIZE        /* keep primary type on top
                      if a7 <> BEAM_FLAG and a7 <> BEAM_CODE     /* and don't move beam flags, etc.
                        ts(sct+1,a7) = ts(a3,a7)        /* make hole for new element
                        ts(a3,a7)    = ts(a4,a7)        /* move in new element
                        ts(a4,a7)    = ts(sct+1,a7)     /* put old element in vacancy
                      end
                    repeat
                  end
                repeat
              repeat

          Rewrite stem flags

              loop for a3 = a1 to a2
                if a3 = a1
                  ts(a3,STEM_FLAGS) = a5 + 0x04       /* turn bit 2
                else
                  ts(a3,STEM_FLAGS) = a5 + 0x0c       /* turn bits 2 and 3 (01-31-97 added a5)
                end
                a4 = a3 - a1 + 1 << 4
                ts(a3,STEM_FLAGS) += a4               /* note number in chord
              repeat
            else
              a2 = a1
            end

          Put in y location of object, y location of end note head
            and (tentitive) y location of end of stem.

            if bit(1,ts(a1,STEM_FLAGS)) = UP
              a4 = ts(a1,STAFFLOC)
              a5 = ts(a2,STAFFLOC)
              a6 = ts(a1,STAFFLOC)
              if a6 >= vpar(5)
                c3 = vpar(7)
              else
                c3 = vpar(6)
                if ts(a1,NTYPE) > EIGHTH and a6 < 0 - vpar(1)
                  c3 -= vpar(1)
                  c3 = vpar(5)
                end
              end
              if nodtype <> NOTE and c3 > vpar(5)
                c3 -= vpar(1)
                if c3 = vpar(6)
                  c3 = vpar(5)
                else
                  c3 = vpar(6)
                end
              end
              a6 -= c3
              a6 += vpar(1)              /* FUDGE
              if a6 > vpar(5)
                a6 = vpar(5)
              end
            else
              a4 = ts(a2,STAFFLOC)
              a5 = ts(a1,STAFFLOC)
              a6 = ts(a2,STAFFLOC)
              if a6 <= vpar(3)
              if a6 <= vpar(4)          /* 09/22/05 was vpar(3)
                c3 = vpar(7)
              else
                c3 = vpar(6)
                if ts(a1,NTYPE) > EIGHTH and a6 >= vpar(10)
                  c3 -= vpar(1)
                  c3 = vpar(5)
                end
              end
              if nodtype <> NOTE and c3 > vpar(5)
                c3 -= vpar(1)
                if c3 = vpar(6)
                  c3 = vpar(5)
                else
                  c3 = vpar(6)
                end
              end
              a6 += c3
              a6 -= vpar(1)              /* FUDGE
              if a6 < vpar(3)
                a6 = vpar(3)
              end
            end
            loop for a3 = a1 to a2
              ts(a3,OBY) = a4
              ts(a3,VIRT_NOTE) = a5
              ts(a3,VIRT_STEM) = a6
            repeat
            a1 = a2         /* advance index to last note of chord
          end
        repeat

    Now we can make a "best guess" about what the beam height for those
    notes (chords) belonging to a beam.  Store the modified height
    (for all notes of the chord) in VIRT_STEM.

        loop for a1 = oldsct+1 to sct
          nodtype = ts(a1,TYPE)
          if chr(nodtype) in [NOTE,CUE_NOTE,GR_NOTE]
            c5 = ts(a1,BEAM_FLAG)
            if c5 <> NO_BEAM
              c3 = ts(a1,PASSNUM)
              c4 = nodtype + 2 / 3      /* 1, 2, or 3
              if c5 = START_BEAM
                passcnt(c3,c4) = 0
              end
              ++passcnt(c3,c4)
              c6 = passcnt(c3,c4)
              beamdata(c4,c3,c6) = a1       /* index to this note

              if c5 = END_BEAM
                stem = bit(1,ts(a1,STEM_FLAGS))
                c8 = 1
                if stem = DOWN
                  c8 = -1
                end
                if c4 = 1
                  c5 = 0
                else
                  c5 = 1
                end
                loop for c7 = 1 to c6
                  c1 = beamdata(c4,c3,c7)
                  mf(c7) = ts(c1,OBY)            /*  vpar(7) * c8 + ts(c1,VIRT_STEM)
                  beamcode(c7) = ts(c1,BEAM_CODE)
                repeat
                perform guessbeam (c10, c11)

           Put in "new" values for virtual stem position

                loop for c7 = 1 to c6
                  c9 = c7 - 1 * vpar(6) * c10 / BHPAR1
                  c1 = beamdata(c4,c3,c7)
                  ts(c1,VIRT_STEM) = c11 + c9
                repeat
              end
            end
          end
        repeat

        loop for a1 = oldsct+1 to sct
          nodtype = ts(a1,TYPE)
          if chr(nodtype) in [XNOTE,XCUE_NOTE,XGR_NOTE]
            ts(a1,VIRT_STEM) = ts(a1-1,VIRT_STEM)
          end
        repeat

    If mcat = 2, decode all accidentals using a measax array which depends
    on the note position in a chord.

        if mcat = 2                /* %%% add code here for changing ax behavior
          loop for a1 = oldsct+1 to sct
            nodtype = ts(a1,TYPE)
            if nodtype <= NOTE_OR_REST
              a4 = ts(a1,STEM_FLAGS) >> 4     /* Note number in chord
              if a4 = 0
                a4 = 1
              end
              if a4 > 4                                 /* 06/04/08 was 3
                putc This code will not work with more than 4 notes in chord
                examine
                stop
              end
              perform decodeax (a1,a4)
            end
            if nodtype = BAR_LINE
              loop for a3 = 1 to 50
                loop for a4 = 1 to 4                    /* 06/04/08 was 3
                  measax(a4,a3) = claveax(a3)
                  measax(a4,a3) = tclaveax(a3)          /* New 12/14/07
                repeat
              repeat
            end
            if nodtype = CLEF_CHG
              a4 = ts(a1,STAFF_NUM) + 1    /* staff number
              clef(a4) = ts(a1,CLEF_NUM)
              perform zjcline (a4)
*     this resets clef and cline
              ts(a1,CLEF_FONT) += z        /* music font
              ts(a1,TRANS_FLAG) = k
              ts(a1,CLEF_STAFF_POS) = 5 - j * notesize
              a3 = hpar(8) * 5 / 6                           /* Added 06-24-94
              if ts(a1,CLEF_FONT) > 128     /* music font
                a3 = a3 * 8 / 10
              end
              ts(a1,SPACING) = a3
              if nstaves > 1     /* Case: assume one part to stave (usual case)
                loop for a3 = 1 to 50
                  measax(a4,a3) = claveax(a3)
                  measax(a4,a3) = tclaveax(a3)          /* New 12/14/07
                repeat
              else
                loop for a4 = 1 to 4                    /* 06/04/08 was 3
                  loop for a3 = 1 to 50
                    measax(a4,a3) = claveax(a3)
                    measax(a4,a3) = tclaveax(a3)        /* New 12/14/07
                  repeat
                repeat
              end
            end
          repeat
        end

    Decode all accidentals for all other cases

        if mcat < 2
          loop for a1 = oldsct+1 to sct
            nodtype = ts(a1,TYPE)
            if nodtype <= NOTE_OR_REST
              a4 = ts(a1,STAFF_NUM) + 1    /* staff number
              perform decodeax (a1,a4)
            end
            if nodtype = BAR_LINE
              loop for a3 = 1 to 50
                loop for a4 = 1 to 4                    /* 06/04/08 was 3
                  measax(a4,a3) = claveax(a3)
                  measax(a4,a3) = tclaveax(a3)          /* New 12/14/07
                repeat
              repeat
            end
            if nodtype = CLEF_CHG
              a4 = ts(a1,STAFF_NUM) + 1    /* staff number
              clef(a4) = ts(a1,CLEF_NUM)
              perform zjcline (a4)
*     this resets clef and cline
              ts(a1,CLEF_FONT) += z         /* music font
              ts(a1,TRANS_FLAG) = k
              ts(a1,CLEF_STAFF_POS) = 5 - j * notesize
              a3 = hpar(8) * 5 / 6                           /* Added 06-24-94
              if ts(a1,CLEF_FONT) > 128     /* music font
                a3 = a3 * 8 / 10
              else
                a3 = a3 * 6 / 5                              /* Added 12/09/03 as a cludge
              end
              ts(a1,SPACING) = a3
              loop for a3 = 1 to 50
                measax(a4,a3) = claveax(a3)
                measax(a4,a3) = tclaveax(a3)            /* New 12/14/07
              repeat
            end
          repeat
        end

    Now remove all places where accidentals have been placed twice on
    the same line as a result of multiple parts playing the same
    altered note.  This code added 09/22/93

        loop for a1 = oldsct+1 to sct
          nodtype = ts(a1,TYPE)
          if nodtype <= NOTE_OR_REST
            loop for a2 = a1 + 1 to sct
            repeat while ts(a2,SPACING) = 0 and ts(a2,DIV) = ts(a1,DIV) and ts(a2,TYPE) <= NOTE_OR_REST
            --a2
            if a2 > a1
              loop for a3 = a1 to a2
                if ts(a3,AX) > 0
                  loop for a4 = a3 + 1 to a2
                    if ts(a4,STAFF_NUM) = ts(a3,STAFF_NUM)
                      if ts(a4,CLAVE) = ts(a3,CLAVE)
                        if ts(a4,AX) = ts(a3,AX)
                          ts(a4,AX) = 0
                        end
                      end
                    end
                  repeat
                end
              repeat
            end
            a1 = a2
          end
        repeat

    Set backtie for division 1 elements in the ts() array.
 
      If this is the measure in a group of measures, then
      BACKTIE for division 1 will point to a ROW element of tiearr,
      otherwise (2) BACKTIE for division 1 will point to the ts() ROW
      element that originated the tie.
 
        loop for a1 = 1 to MAX_TIES
          if tiearr(a1,TIE_SNUM) > 0 and tiearr(a1,TIE_FOUND) = 0


      Case 1:  division 1 of first measure in group

            if oldsct = 0
              loop for a2 = 1 to sct
                if ts(a2,DIV) = 1
                  a3 = tiearr(a1,TIE_NTYPE)
                  a4 = ts(a2,TYPE)
                  xbyte = chr(a3) // chr(a4)
                  if ts(a2,STAFFLOC) = tiearr(a1,TIE_VLOC)
                    if ts(a2,STAFF_NUM) = tiearr(a1,TIE_STAFF)
                      if ts(a2,BACKTIE) = 0
                        if xbyte in [NOTE,XNOTE]    /* i.e., both a3 and a4 are in set
                          ts(a2,BACKTIE) = a1 + INT10000   /* backtie = tie number
                          goto TS1
                        end
                        if xbyte in [CUE_NOTE,XCUE_NOTE]
                          ts(a2,BACKTIE) = a1 + INT10000   /* backtie = tie number
                          goto TS1
                        end
                      end
                    end
                  end
                end
              repeat
              return 3
            else

      Case 2:  division 1 for subsequent measures in group

              loop for a2 = oldsct+1 to sct
                if ts(a2,DIV) = 1
                  a3 = tiearr(a1,TIE_NTYPE)
                  a4 = ts(a2,TYPE)
                  xbyte = chr(a3) // chr(a4)
                  if ts(a2,STAFFLOC) = tiearr(a1,TIE_VLOC)
                    if ts(a2,STAFF_NUM) = tiearr(a1,TIE_STAFF)
                      if xbyte in [NOTE,XNOTE]    /* i.e., both a3 and a4 are in set
                        ts(a2,BACKTIE) = tiearr(a1,TIE_NDX)   /* backtie = ts index
                        tiearr(a1,TIE_SNUM) = 0   /* free-up this ROW element of tiearr
                        goto TS1
                      end
                      if xbyte in [CUE_NOTE,XCUE_NOTE]
                        ts(a2,BACKTIE) = tiearr(a1,TIE_NDX)   /* backtie = ts index
                        tiearr(a1,TIE_SNUM) = 0   /* free-up this ROW element of tiearr
                        goto TS1
                      end
                    end
                  end
                end
              repeat
              return 3
            end
TS1:
            tiearr(a1,TIE_FOUND) = 1
          end
        repeat

    Set backtie for all non-division-1 elements in the ts() array.
 
        loop for a1 = oldsct+1 to sct

      Special case: Grace note tied to a regular note on the same division 11/02/05

          if chr(ts(a1,TYPE)) in [GR_NOTE,XGR_NOTE]
            if bit(0,ts(a1,SUPER_FLAG)) = 1 and a1 < sct      /* tie present
              a4 = ts(a1,DIV)
              loop for a2 = a1+1 to sct
                if ts(a2,DIV) = a4
                  if ts(a1,STAFF_NUM) = ts(a2,STAFF_NUM)
                    if ts(a1,STAFFLOC) = ts(a2,STAFFLOC)
                      if chr(ts(a2,TYPE)) in [NOTE,XNOTE]
                        ts(a2,BACKTIE) = a1     /* Case: backtie = ts index to first note
                        goto SEARCH_DONE
                      end
                    end
                  end
                else
                  a2 = 1000000
                end
              repeat
            end
          end

      End of 11/02/05 special case

          if chr(ts(a1,TYPE)) in [NOTE,XNOTE,CUE_NOTE,XCUE_NOTE]
            if bit(0,ts(a1,SUPER_FLAG)) = 1 and a1 < sct      /* tie present
              a4 = ts(a1,DIV) + ts(a1,NOTE_DUR)

         Try it first where pass numbers must be the same (usual case)

              loop for a2 = a1+1 to sct
                if ts(a2,DIV) = a4 and ts(a1,PASSNUM) = ts(a2,PASSNUM)
                  if ts(a1,STAFFLOC) = ts(a2,STAFFLOC)
                    if chr(ts(a1,TYPE)) in [NOTE,XNOTE]
                      if chr(ts(a2,TYPE)) in [NOTE,XNOTE]
                        ts(a2,BACKTIE) = a1     /* Case: backtie = ts index to first note
                        goto SEARCH_DONE
                      end
                    else
                      if chr(ts(a2,TYPE)) in [CUE_NOTE,XCUE_NOTE]
                        ts(a2,BACKTIE) = a1     /* Case: backtie = ts index to first note
                        goto SEARCH_DONE
                      end
                    end
                  end
                end
              repeat

         Now try it where pass numbers need not be the same (unusual case)

              loop for a2 = a1+1 to sct
                if ts(a2,DIV) = a4
                  if ts(a1,STAFFLOC) = ts(a2,STAFFLOC)
                    if chr(ts(a1,TYPE)) in [NOTE,XNOTE]
                      if chr(ts(a2,TYPE)) in [NOTE,XNOTE]
                        ts(a2,BACKTIE) = a1     /* Case: backtie = ts index to first note
                        goto SEARCH_DONE
                      end
                    else
                      if chr(ts(a2,TYPE)) in [CUE_NOTE,XCUE_NOTE]
                        ts(a2,BACKTIE) = a1     /* Case: backtie = ts index to first note
                        goto SEARCH_DONE
                      end
                    end
                  end
                end
              repeat

     If you reach this point (i.e., you have not found a terminating
     note), then you must use the tiearr to temporarily store the
     information about this note for future reference.  This info must
     be discarded before the final processing of the ts() array.


*      identify free slice of tiearr
              loop for c7 = 1 to MAX_TIES
                if tiearr(c7,TIE_SNUM) = 0
                  goto XXX2
                end
              repeat

           Here is where the pseudo tiearr is built

XXX2:         tiearr(c7,TIE_SNUM)  = INT1000000       /* pseudo super number
              tiearr(c7,TIE_NTYPE) = ts(a1,TYPE)
              tiearr(c7,TIE_VLOC)  = ts(a1,STAFFLOC)
              tiearr(c7,TIE_NDX)   = a1
              tiearr(c7,TIE_STAFF) = ts(a1,STAFF_NUM)
              tiearr(c7,TIE_FOUND) = 0
              tiearr(c7,TIE_FORCE) = ts(a1,SLUR_FLAG) >> 24
       /* 04/20/03: New code
              c6 = ts(a1,TSR_POINT)
              tiearr(c7,TIE_SUGG)  = ors(tsr(c6){69,4})
            end
          end
SEARCH_DONE:
        repeat

   Determine space parameter for notes and figures (and isolated signs, words and marks)

        loop for a1 = 1 to 120
          mf(a1) = 0
        repeat
        a9 = 0
        divspq = olddivspq
        inctype_rem = 0                            /* Code added 02/24/97
        loop for a1 = oldsct+1 to sct
          nodtype = ts(a1,TYPE)
          if nodtype = DIV_CHG
            mdiv = ts(a1,DIV)
            divspq = ts(a1,DIVSPQ)
          end
          if nodtype = METER_CHG
            perform newnsp
          end
          if nodtype > NOTE_OR_REST and nodtype <> FIGURES
            if chr(nodtype) in [SIGN,WORDS,MARK] and ts(a1,ISOLATED) = 1
            else
              goto TS3
            end
          end
          if chr(nodtype) not_in [XNOTE,XCUE_NOTE,XGR_NOTE]
            if nodtype = GR_NOTE
              goto TS3       /* grace note spacing has already been computed. see GRACE
            end

      determine space and duration for this note/figure

            if nodtype <= NOTE_OR_REST
              a5 = a1
              perform getspace
              a7 = a6
              a8 = ts(a1,NOTE_DUR)

      Code added 05-29-94   We cannot allow a8 to be less than time
                            distance to the next division.

      Code added 06-18-94   We also cannot allow a8 to be more than the
                            time distance to the next division, if the
                            next division contains an isolated sign,
                            words, or mark.

              loop for a2 = a1+1 to sct
                a3 = ts(a2,DIV) - ts(a1,DIV)
                if a3 > 0
                  if a3 > a8
                    a8 = a3
                  end
                  if chr(ts(a2,TYPE)) in [SIGN,WORDS,MARK] and ts(a2,ISOLATED) = 1
                    if a3 < a8
                      a8 = a3
                    end
                  end
                  a2 = sct
                end
              repeat
            else

    case 2: figures (and isolated signs, words, and marks)

      1) determine duration (given or implied)

              if nodtype = FIGURES and ts(a1,FIG_DUR) > 0
                a8 = ts(a1,FIG_DUR)
              else
        if figure is not isolated, adopt a duration, else
          impute duration
                if a1 <> sct
                  loop for a11 = a1+1 to sct
                    if ts(a11,DIV) = ts(a1,DIV)
                      if ts(a11,TYPE) <= NOTE_OR_REST
                        a8 = ts(a11,NOTE_DUR)
                        goto TS4
                      end
                    else
              isolated figure in middle of data
                      a8 = ts(a11,DIV) - ts(a1,DIV)
                      goto TS4
                    end
                  repeat
                end
              isolated figure at end of data
                a8 = divspq
              end

      2) compute space for this duration


TS4:          a10 = a8

         a) adjust duration for triplet
              a12 = 0
              a11 = divspq / 3
              if rem = 0
                a11 = a10 / 3
                if rem > 0
                  a10 = a10 * 3 / 2
                  a12 = 1
                end
              end
         b) find index into space parameter array
              a11 = 35 - a12
              a12 = divspq * 16
              loop
                a13 = a10 / a12
                a12 >>= 1
                a11 -= 3
              repeat while a13 = 0
              if rem > 0
                ++a11
              end
              a7 = nsp(a11)
            end
            a14 = a7

     notes and figures re-unified at this point in program

    a7 = space for first note/figure in node
    a8 = duration for first note/figure in node
   a14 = largest space for shortest full duration on this division (initially a14 = a7)

            ++a9
            ts(oldsct+a9,TEMP1) = a7
            ts(oldsct+a9,TEMP2) = a8
            mf(a9) = a8

     proceeding from this point, we have only regular and cue notes,
                      rests and chords on this division

            if a1 < sct
              loop for a2 = a1+1 to sct
                if ts(a2,DIV) <> ts(a1,DIV)
                  --a2
                  goto TS2
                else
                  a11 = ts(a2,TYPE)
                  if a11 <> XNOTE and a11 <> XCUE_NOTE
                    a5 = a2
                    perform getspace
                    a15 = ts(a2,NOTE_DUR)

      12/04/05  This code moved from below (before modifying a15)
 
                    ++a9
                    mf(a9) = a15
      
                    if a15 < a8                        /* modified 3/20/94
                      a7 = a6
                      a14 = a7

        Code added 05-29-94   We cannot allow the "time-space increment"
                              to be less than the time distance to the
                              next division.

                      loop for a3 = a2+1 to sct
                        if ts(a3,DIV) <> ts(a1,DIV)
                          a15 = ts(a3,DIV) - ts(a1,DIV)
                          a8 = a15
                          a3 = sct
                        end
                      repeat
                    else
                      if a15 = a8
                        if a6 < a7
                          a7 = a6
                        end
                        if a6 > a7
                          a14 = a6
                        end
                      end
                    end

            12/04/05  Moving this code to a point before a15 is modified
 
                    ++a9
                    mf(a9) = a15


                    ts(oldsct+a9,TEMP1) = a6
                    ts(oldsct+a9,TEMP2) = a15
                  end
                end
              repeat
              a2 = sct
            else
              a2 = a1
            end
    a2 = pointer into set for last figure/note/rest/cue
                 on this division
    a7 = smallest space for notes for shortest duration on this division
    a8 = duration of notes of shortest duration on this division
    a9 = total size of mf array (notes longer than smallest)
   a14 = largest space for shortest full duration on this division
TS2:
            a4 = 10000
            a5 = 10000
            a6 = a7
            loop for a3 = 1 to a9
              if mf(a3) > 0
                if mf(a3) < a4
                  a4 = mf(a3)
                end

           07/01/03:  Fixing this to account for irests with null space

                if ts(oldsct+a3,TEMP2) <= a5
                if ts(oldsct+a3,TEMP2) < a5
                  a5 = ts(oldsct+a3,TEMP2)
                  if ts(oldsct+a3,TEMP1) > 0
                    a6 = ts(oldsct+a3,TEMP1)
                  end
                  a6 = ts(oldsct+a3,TEMP1)
                end
              end
            repeat
    a4 = smallest number of divisions from left over notes
    a5 = duration of shortest note sounding at this point
    a6 = space parameter for this shortest note
    a4 < a8 means syncopation
    here also is where we set the increment distance flag.
       Since we are going to increment the distance, we
       know at this point what technique we will be using.
       ts(24) describes this technique.

            if a4 < a8
              a7 = a6 * a4 / a5
              a8 = a4
            else
              a7 = a14
            end
    a7 = space parameter for this node
    a8 = real duration of this node
            dv4 = 576 * a8 / divspq
            inctype_rem += rem                     /* Code added 02/24/97
            if inctype_rem > (divspq / 2)
              inctype_rem -= divspq
              ++dv4
            end                                    /* End of 02/24/97 addition
            ts(a1,DINC_FLAG) = dv4
            loop for a3 = 1 to a9
              mf(a3) -= a8
              if mf(a3) < 0
                mf(a3) = 0
              end
            repeat
            if chr(nodtype) in [SIGN,WORDS,MARK]
              ts(a1,SPACING) = a7                  /* must be small, but non-zero
            else
              if nodtype <= NOTE_OR_REST
                ts(a1,SPACING) = a7
              else
                if a1 = a2
                  ts(a1,FIG_SPACE) = a7
                  ts(a1,MIN_FIG_SPAC) = a7
                else
                  a6 = a1 + 1
                  if ts(a6,TYPE) <= NOTE_OR_REST
                    ts(a6,SPACING) = a7
                  else
                    return 8
                  end
                end
              end
            end
            a1 = a2
          end
TS3:    repeat

        /* for debug purposes only
        if inctype_rem <> 0
          putc Logical Problem with typeinc_rem
          putc Check it out!
        end


    Update olddivspq

        olddivspq = divspq
        if mdiv = totdiv  /*  added 1-27-93    This code is necessary
          qflag = 0       /*  to cope with the situation where the
        end               /*  divisions-per-quarter is changed at the
                          /*  end of the measure

*
        loop for a1 = 1 to a9
          ts(oldsct+a1,TEMP1) = 0
          ts(oldsct+a1,TEMP2) = 0
        repeat

    Space parameter is initialized


    We have computed ts(24), the distance increment flag, for all
    regular/cue/figure nodes.  This parameter is the time elaps
    between this node and the next node in the measure.  It is
    measured in divisions, with 576 divisions being the equivalent
    of a quarter note.  In the example below the notes are triplet
    eights and regular sixteenths respectively.  The distances are
    listed by letter.

                    :=======:=======:
       triplet 8ths |       |       |       |    a =  144 (reg 16th)
                    @       @       @       O    b =   48
                    /  a  /b/ c / d /e/  f  /    c =   96
                    @     @     @     @     O    d =   96
       sixteenths   |     |     |     |     |    e =   48
                    |_____|_____|_____|          f =  144 (reg 16th)
                    *=====*=====*=====*

    These parameters will be assigned to the first object in the
    node FOLLOWING THE DISTANCE, whatever it is.  It might, for
    example, be a grace note, or some kind of sign.  The first
    object in the node is the one where we can best describe the
    distance that has been traversed.  In order to accomplish this,
    we do not set the inctype parameter until after the object
    containing the ts(24) parameter is processed.  When spn rolls
    over to a new value, the object in question will be assigned
    the prior ts(24) parameter.

        tfirstsp = 0

 ***************************************************************
    Debug Information

        g = measnum - 1
        if bit(2,pmode) = 1 and g >= debug_point

     Condition changed 01/01/06

        if (bit(2,pmode) = 1 or debug_flag = 1) and g >= debug_point
          putc   Set Array at Point No. 1:  measure ~g
          putc Look?
          getc jtype
          if jtype = "y"
            perform display_ts
          end
        end

    End debug information
 ***************************************************************

    Adjust accidentals for case where tie crosses bar line

        a10 = 1
        loop for a1 = oldsct+1 to sct
          nodtype = ts(a1,TYPE)
          if ts(a1,DIV) = a10 and ts(a1,BACKTIE) > 0
            if chr(nodtype) in [NOTE,XNOTE,CUE_NOTE,XCUE_NOTE]
              loop for a3 = a1+1 to sct
                if ts(a3,DIV) > a10 and ts(a3,TYPE) <= NOTE_OR_REST
                  if ts(a3,CLAVE) = ts(a1,CLAVE)
                    if ts(a3,STAFF_NUM) = ts(a1,STAFF_NUM)    /* added 3-23-94
                      if ts(a3,AX) = 0
                        ts(a3,AX) = ts(a1,AX)
                      end

                    Now remove any similar accidentals which might have
                    existed previously on this <pitch, staff, division>
                    combination.

                      loop for a4 = a3 + 1 to sct
                      repeat while ts(a4,SPACING) = 0 and ts(a4,DIV) = ts(a3,DIV) and ts(a4,TYPE) <= NOTE_OR_REST
                      --a4
                      loop for a5 = a3 + 1 to a4
                        if ts(a5,STAFF_NUM) = ts(a3,STAFF_NUM)
                          if ts(a5,CLAVE) = ts(a3,CLAVE)
                            if ts(a5,AX) = ts(a3,AX)
                              ts(a5,AX) = 0
                            end
                          end
                        end
                      repeat
                      goto XD
                    end
                  end
                end
              repeat
XD:
              if ts(a1,AX) > 0
              if ts(a1,AX) > 0 and (ts(a1,SUBFLAG_1) & 0x040000) = 0 /* condition added 11/05/05
                ts(a1,AX) |= 0x10       /* Code added 02/25/97.  This is the "silent" flag
              end
            end
          end
          if nodtype = BAR_LINE       /* non-controlling case
            a10 = ts(a1,DIV)
          end
        repeat


     We have a tiny chore to do here.  In the case where we have
     a down-up pattern of stems on the same beam, we need to be
     sure the spacing between these notes is at least some minimum
     distance.  (This code will work most of the time).

        a5 = hpar(4) * 4 / 5 + hpar(82)
        a4 = 0
        loop for a1 = oldsct+1 to sct
          nodtype = ts(a1,TYPE)
          if nodtype <= NOTE_OR_REST
            a3 = nodtype + 1 / 3        /* This code assumes
            if rem <> 0                 /* XNOTE=2  XCUE_NOTE=5  XGR_NOTE=8
              if ts(a1,SPACING) > 0
                a4 = a1                 /* save index to spacing number
              end
            end
            if nodtype = NOTE or nodtype = GR_NOTE or nodtype = CUE_NOTE
              if bit(1,ts(a1,STEM_FLAGS)) = UP
                c12 = ts(a1,BEAM_FLAG)
                if c12 = CONT_BEAM or c12 = START_BEAM
                  a3 = 0
                  loop for a2 = a1 + 1 to sct
                    if ts(a2,SPACING) > 0
                      ++a3
                      if a3 > 1
                        goto NEXTNOTE
                      end
                    end
                    if ts(a2,TYPE) = nodtype
                      if ts(a2,PASSNUM) = ts(a1,PASSNUM)
                        if bit(1,ts(a2,STEM_FLAGS)) = DOWN
                          if a4 = 0
                            putc Program error
                            examine
                          end
                          if ts(a4,SPACING) < a5
                            ts(a4,SPACING) = a5
                          end
                        end
                        goto NEXTNOTE
                      end
                    end
                  repeat
                end
              end
            end
          end
NEXTNOTE:
        repeat

     Make space for text

     This is not an easy task to perform.  I have tried a couple of
     methods already and am not too happy with them.  Let me start
     by summarizing the objectives.

     1) We want to underlay the text in as compact a way as possible
          The reason for this is that in the later stages of typesetting
          we almost always expand the music, so we want to start with
          as compact a version as possible.

     2) We want the notes to be as true to their rythmic values as
          possible.

     3) We need to preserve spacings attached to grace notes, clef
          signs, key changes, etc.

        a2 = firstoff
        a3 = hpar(37) + tfirstsp
        a11 = 0
        c11 = 0                             /* added 12/09/03
        loop for a1 = oldsct+1 to sct
          nodtype = ts(a1,TYPE)
          if nodtype = NOTE
            a8 = ts(a1,TEXT_INDEX)
            temp2 = trm(tsdata(a8))
            temp2 = temp2 // pad(1)

            if temp2{1} in ['A'..'Z','a'..'z','!'..'(','\','=']


         New test for text data 09/01/03

            c6 = 0
            if temp2{1} in ['A'..'Z','a'..'z','!'..'(','\','=']
              c6 = 1
            else
              temp2 = temp2 // " "
              loop for c7 = 1 to len(temp2)
                if temp2{c7} = "|" and temp2{c7+1} in ['A'..'Z','a'..'z','!'..'(','\','=']
                  c6 = 1
                  c7 = len(temp2)
                end
              repeat
              temp2 = trm(temp2)
            end
            if c6 = 1

         End of test 09/01/03

              c11 = 1                       /* added 12/09/03
              textconflag = OFF

     Look for case of multiple text

              c6 = 0
              c7 = 0
              temp2 = temp2 // "| "
CCCB:
              if temp2 con "|"
                ttext = temp2{1,mpt-1}
                                            We don't do this here because it will
                perform kernttext           screw things up later.  We are willing
                                            to live with an approximate word length
                temp2 = temp2{mpt+1..}
                c5 = mtfont
                perform wordspace
                a6 = len(ttext)
                if "-_" con ttext{a6}
                  if mpt = 1
                    a5 -= spc(45)
                  else
                    a5 -= spc(95)
                  end
                else
                  c7 = 1
                end
                if c6 < a5
                  c6 = a5
                end
                goto CCCB
              end
              a5 = c6
              if c7 = 0    /* all words end in "_" or "-"
                if a1 <> sct and ts(a1+1,TYPE) = NOTE
                  c8 = ts(a1+1,TEXT_INDEX)
                  temp2 = trm(tsdata(c8))
                  temp2 = temp2 // pad(1)
                  if "-_" con temp2{1}
                    a4 = a5 - ts(a1,SPACING) - hpar(51) / 3
                    if a4 < 0
                      a4 = 0
                    end
                    goto CCCC
                  end
                end
                if bit(0,ts(a1,SUPER_FLAG)) = 1
                  a4 = a5 - ts(a1,SPACING) - hpar(51) / 3
                  if a4 < 0
                    a4 = 0
                  end
                  goto CCCC
                end
              else                                      /* 12/09/03 try removing this
                if a1 <> oldsct+1
                  c8 = ts(a1-1,TEXT_INDEX)              /* This code is a cludge and
                  temp2 = trm(tsdata(c8))               /* and is no longer an addition.
                  temp2 = temp2 // pad(1)               /* The 12/09/03 post-adjustment
                  if "-_" con temp2{1}                  /* provides a much better fix.
                    a4 = a5 >> 1 - (spc(45) >> 1)
                    goto CCCC
                  end
                end
              end
              a4 = a5 / 3 - (spc(45) >> 1)

CCCC:         a6 = a3 - a4
              a7 = a2 - a6

   a5       = projected space taken up by syllable
   a4       = amount by which a syllable is backed up from the note
                  position
   tfirstsp = amount by which first note is shifted forward to make
                  space for text
   a3       = projected position of current note from bar line
   a6       = projected position of beginning of current syllable
   firstoff = amount by which last syllable from previous measure
                  overhangs the space allowed for the last note
   a2       = smallest value of a6 allowed
   a7       = difference between smallest allowed a6 and current a6


              if a7 > 0
                if a11 = 0
                  tfirstsp += a7
                  a3 += a7
                else
                  if ts(a10,TYPE) = NOTE
                    c8 = ts(a10,TEXT_INDEX)
                    temp2 = trm(tsdata(c8))
                    temp2 = temp2 // pad(1)
                    if "-_" con temp2{1}
                      c9 = 0
                      loop for c10 = a10 - 1 to oldsct + 1 step -1
                        if ts(c10,SPACING) > 0 and ts(c10,TYPE) < GR_NOTE
                          c9 = c10
                          c10 = 0
                        end
                      repeat
                      if c9 > 0
                        ts(c9,SPACING) += a7 >> 1
                        ts(a10,SPACING) += a7 >> 1
                        goto CCCA
                      end
                    end
                  end
                  ts(a10,SPACING) += a7     /* a10 set later
                end
                a3 += a7
              end
CCCA:
              tsdata(a8) = trm(tsdata(a8)) // "$$$$" // chs(a4)

              a5 -= a4
              a2 = a3 + a5 + hpar(58)       /* hpar(58) = space between words
            end
            if temp2{1} = "_"
              a5 = a3 + spc(95)
              if a5 > a2
                a2 = a5
              end
            end

            temp2 = trm(tsdata(a8))
            temp2 = temp2 // pad(1)
            if temp2{1} = "_"
              textconflag = ON
            end

            sub = 1
            a11 = 1
            loop while temp2{sub..} con "|"
              a11 <<= 1
              ++sub
              if temp2{sub} = "_"
                textconflag += a11
              end
            repeat

            if temp2 = " " and textconflag > OFF     /* code added 02-23-95
              tsdata(a8) = pad(10)
              loop for a11 = 0 to 9
                if bit(a11,textconflag) = ON
                  tsdata(a8){a11+1} = "~"
                end
              repeat
              tsdata(a8) = trm(tsdata(a8))
              textconflag = OFF
            end
            a11 = 1
          end
          if nodtype = REST and ts(a1,CLAVE) < 200   /* code added 02-23-95
            textconflag = OFF
          end
          if nodtype = BAR_LINE
            if a2 - hpar(36) > a3
              ts(a10,SPACING) += a2 - hpar(36) - a3
              a3 = a2 - hpar(36)
            end
          end

*   a10 = backpointer to prior space for note/rest object set
          if ts(a1,SPACING) > 0 and ts(a1,TYPE) < GR_NOTE
            a10 = a1
          end
          firstoff = 0
          if a1 = sct
            a4 = a2 - hpar(36)
            if a4 > a3
              firstoff = a4 - a3
            end
          else
            a3 += ts(a1,SPACING)
          end
        repeat

     Adding a new section of code (12/09/03) which attempts to midigate somewhat
     the unevenness in note spacing introduced by the addition of text.  Code
     uses c11 to c17 as temporary variables, as well as a new array variable nspace(.,.)

        if c11 = 1
          c12 = 0
          loop for a1 = oldsct+1 to sct
            nodtype = ts(a1,TYPE)
            if nodtype = NOTE or nodtype = REST
              a8 = ts(a1,TEXT_INDEX)
              temp2 = trm(tsdata(a8))
#if REPORT4
              putc a1 = ~a1 .t10 NTYPE = ~ts(a1,NTYPE) .t22 SPACING = ~ts(a1,SPACING) .t37 ...
              putc TYPE = ~ts(a1,TYPE) .t12 text = ~temp2
#endif
              ++c12
              nspace(c12,1) = a1
              nspace(c12,2) = ts(a1,NTYPE)
              nspace(c12,2) = ts(a1,NTYPE) & 0xff           /* new 10/15/07
              nspace(c12,3) = ts(a1,SPACING)
              nspace(c12,4) = ts(a1,TYPE)
              if temp2 con "$$$$"
                nspace(c12,5) = int(temp2{mpt+4..})
              else
                nspace(c12,5) = 0
              end
              nspace(c12,6) = 0
              nspace(c12,7) = 0
              nspace(c12,8) = 0

            end
          repeat

  Algorithm.

  (1) examine all pairs of notes.  Find the pair for which
      (a) same duration
      (b) if d1 = distance after 1st note, and d2 = distance after 2nd note
            and both d1 and d2 are non-zero                     (added 04/10/05)
            and abs(d1 - d2) > 1
      (c) smallest distance in this set

  (2) try moving 2nd note one unit either towards (d1 > d2) or away from (d2 > d1) first note.
      (a) resulting total shift of 2nd note cannot more than 1/2 nspace(.,5) to the right
            or more than nspace(.,5) to the left
      (b) if note cannot be moved, goto (1) and consider next pair

  (3) if (1)+(2) fail, look for situations where
      (a) a note of longer duration follows a note of shorter duration, and
            the shorter note is allowed more space.  Try moving the 2nd note
            closer to the first, then goto (1).
      (b) a note of shorter duration follows a note of longer duration, and
            the shorter note is allowed more space.  Try moving the 2nd note
            away from the first, then goto (1).
      (c) in all cases under (3), principal (2)(a) must be followed,
            and both notes in question must have non-zero following distances (added 04/10/05)


NXPAIR:
#if REPORT4
          loop for c13 = 1 to c12
            loop for c14 = 1 to 6
              putc .w8 ~nspace(c13,c14) ...
            repeat
            putc
          repeat

          putc
          getc
#endif
          c15 = 1000
          c16 = 0
          loop for c13 = 1 to c12 - 1
            if nspace(c13,2) = nspace(c13+1,2)      (new condition below added 04/10/05)
            if nspace(c13,2) = nspace(c13+1,2) and nspace(c13+1,3) <> 0 and nspace(c13,3) <> 0
              c14 = abs(nspace(c13,3) - nspace(c13+1,3))
              if c14 > 1
                if c14 < c15
                  if nspace(c13+1,5) = 0                     /* next node is a rest, etc.
                    if nspace(c13+1,6) > -6                  /* max incroachment is 6
                      c15 = c14
                      c16 = c13
                    end
                  else
                    if nspace(c13,3) > nspace(c13+1,3)       /* move 2nd note to the left
                      if nspace(c13+1,6) < 0
                        if abs(nspace(c13+1,6)) < nspace(c13+1,5)
                          c15 = c14
                          c16 = c13
                        end
                      else
                        c15 = c14
                        c16 = c13
                      end
                    else                                     /* move 2nd note to the right
                      if nspace(c13+1,6) < (nspace(c13+1,5) + 1 >> 1)
                        c15 = c14
                        c16 = c13
                      end
                    end
                  end
                end
              end
            end
          repeat
          if c16 > 0
            loop for c13 = 1 to c12
              nspace(c13,7) = 0
            repeat
          end

          if c16 = 0
            loop for c13 = 1 to c12 - 1
              if nspace(c13,2) = nspace(c13+1,2)       (new condition below added 04/10/05)
              if nspace(c13,2) = nspace(c13+1,2) and nspace(c13+1,3) <> 0 and nspace(c13,3) <> 0
                c14 = abs(nspace(c13,3) - nspace(c13+1,3))
                if c14 = 1 and nspace(c13,7) = 0
                  if nspace(c13+1,5) = 0                     /* next node is a rest, etc.
                    if nspace(c13+1,6) > -6                  /* max incroachment is 6
                      c16 = c13
                      c13 = c12
                    end
                  else
                    if nspace(c13,3) > nspace(c13+1,3)       /* move 2nd note to the left
                      if nspace(c13+1,6) < 0
                        if abs(nspace(c13+1,6)) < nspace(c13+1,5)
                          c16 = c13
                          c13 = c12
                        end
                      else
                        c16 = c13
                        c13 = c12
                      end
                    else                                     /* move 2nd note to the right
                      if nspace(c13+1,6) < (nspace(c13+1,5) + 1 >> 1)
                        c16 = c13
                        c13 = c12
                      end
                    end
                  end
                end
              end
            repeat
            if c16 > 0
              nspace(c16,7) = 1
            end
          end

          if c16 > 0           /* note pair found
            if nspace(c16,3) > nspace(c16+1,3)
              if c16 > 1 and nspace(c16-1,2) > nspace(c16,2) and nspace(c16,6) < nspace(c16,5)
                --nspace(c16,3)
                ++nspace(c16-1,3)
                ++nspace(c16,6)
              else
                --nspace(c16,3)
                ++nspace(c16+1,3)
                --nspace(c16+1,6)
              end
            else
              ++nspace(c16,3)
              --nspace(c16+1,3)
              ++nspace(c16+1,6)
            end
            goto NXPAIR
          end

          loop for c13 = 1 to c12 - 1
            if nspace(c13,3) <> 0 and nspace(c13+1,3) <> 0   /* this condition added 04/10/05
              if nspace(c13,2) > nspace(c13+1,2)
                if nspace(c13,3) < nspace(c13+1,3)
                  if nspace(c13+1,6) < nspace(c13+1,5) or (nspace(c13+1,4) = 3 and nspace(c13+1,6) < 6)
                    ++nspace(c13,3)
                    --nspace(c13+1,3)
                    ++nspace(c13+1,6)
                    goto NXPAIR
                  end
                end
              end
              if nspace(c13,2) < nspace(c13+1,2)
                if nspace(c13,3) > nspace(c13+1,3)
                  if abs(nspace(c13+1,6)) < (nspace(c13+1,5) + 1 >> 1)
                    --nspace(c13,3)
                    ++nspace(c13+1,3)
                    --nspace(c13+1,6)
                    goto NXPAIR
                  end
                end
              end
            end
          repeat
#if REPORT4
          putc NO MORE IMPROVEMENTS
          getc
#endif
          c12 = 0
          loop for a1 = oldsct+1 to sct
            nodtype = ts(a1,TYPE)
            if nodtype = NOTE or nodtype = REST
              a8 = ts(a1,TEXT_INDEX)
              temp2 = trm(tsdata(a8))

              ++c12
              if nspace(c12,1) <> a1
                dputc Program Error
                stop
              end
              ts(a1,SPACING) = nspace(c12,3)

              if temp2 con "$$$$"
                c13 = nspace(c12,5) + nspace(c12,6)
                temp2 = temp2{1,mpt+3} // chs(c13) // "," // chs(nspace(c12,5))
                tsdata(a8) = trm(temp2)
              end
            end
          repeat

        end
       End of 12/09/03 addition

 
     Make space for text (very old version)
 
        a2 = firstoff
        a3 = hpar(37) + tfirstsp
        a11 = 0
        loop for a1 = oldsct+1 to sct
          nodtype = ts(a1,TYPE)
          if nodtype = NOTE
            a8 = ts(a1,TEXT_INDEX)
            ttext = trm(tsdata(a8))
            ttext = ttext // pad(1)
            if ttext{1} in ['A'..'Z','a'..'z','!'..'(','\','=']
              c5 = mtfont
              perform wordspace
              a6 = len(ttext)
              if ttext{a6} = "_"
                a5 -= 20
              end
              if ttext{a6} = "-"
                a5 -= 10
              end
              if ttext{a6} = "_"
                a4 = a5 - ts(a1,SPACING) - hpar(51) / 3
                if a4 < 0
                  a4 = 0
                end
                goto CCCA
              end
              a4 = a5 / 3 - 6
CCCA:         a6 = a3 - a4
              a7 = a2 - a6
 
   a5       = projected space taken up by syllable
   a4       = amount by which a syllable is backed up from the note
                  position
   tfirstsp = amount by which first note is shifted forward to make
                  space for text
   a3       = projected position of current note from bar line
   a6       = projected position of beginning of current syllable
   firstoff = amount by which last syllable from previous measure
                  overhangs the space allowed for the last note
   a2       = smallest value of a6 allowed
   a7       = difference between smallest allowed a6 and current a6
 
              if a7 > 0
                if a11 = 0
                  tfirstsp += a7
                else
                  ts(a10,SPACING) += a7     /* a10 set later
                end
                a3 += a7
              end
              a5 -= a4
              a2 = a3 + a5 + 16             /* 16 = space between words (magic)
            end
            if ttext{1} = "_"
              a5 = a3 + spc(95)
              if a5 > a2
                a2 = a5
              end
            end
            a11 = 1
          end
*   a10 = backpointer to prior space for note/rest object set
          if ts(a1,SPACING) > 0
            a10 = a1
          end
          firstoff = 0
          if a1 = sct
            a4 = a2
            if a4 > a3
              firstoff = a4 - a3
            end
          else
            if nodtype < 11
              a3 += ts(a1,SPACING)
            end
          end
        repeat


 *****************************************************************
   Debugging Information

        if jtype = "y"
          if bit(2,pmode) = 1 and g >= debug_point

     Condition changed 01/01/06

          if (bit(2,pmode) = 1 or debug_flag = 1) and g >= debug_point
            putc   Set Array at Point No. 2: including text, ...
            putc measure ~g
            putc          firstspace = ~tfirstsp
            putc
            perform display_ts
          end
        end


     If there is more that one pass in this measure, one of the
     things we need to know is the number of passes per staff.
     If this number is greater than one for a particular staff,
     then we are going to need to know (1) whether ties have tips
     up or down for each pass, and (2) whether slurs should connect
     to note heads or to stems.

     I propose the following rule:  If there is more than one track
     on a particular staff and if stem directions are consistant
     for each track on that particular staff, then

       (1) tie tips will always go the opposite direction of the
             stem direction
       (2) slurs should connect to stems rather than to note heads

     Before beginning the processing loop, I need to determine the
     situation, since it is dependent on what happens in the entire
     measure.  I propose (6-4-93) to add a new element to the ts(.)
     array, in this case, element 29 = MULTI_TRACK flag.  The meaning
     of this flag will be as follows:

         0 = this note lies on a staff that has notes from only one
               pass.

               In this situation, mcat can be 0, 1 or 2

               (1) mcat = 0 or mcat = 1.   Any tie or slur
               starting or ending on this note will follow the
               rules for a single part on a staff.

               (2) mcat = 2   There is only one pass, but notes
               will occur in chords.  In this case, slurs and
               articulations will mainly fall on the note head at
               the end of the stem.  In the case where both stem
               directions are involved, slurs are generally put
               above the notes (tips down)


         1 = this note belongs to one of multiple passes on this
               staff and all notes on this pass have stems which
               point up.

               In this situation, mcat can be either 0 or 3, depending
               on the value of vflag.  Whatever the case, slurs
               will go above the notes (tips down).


         2 = this note belongs to one of multiple passes on this
               staff and all notes on this pass have stems which
               point down.

               In this situation, mcat can be either 0 or 3, depending
               on the value of vflag.  Whatever the case, slurs
               will go below the notes (tips up).

         3 = this note belongs to one of multiple passes on this
               staff and the stem directions for the note of at least
               one of these passes on this staff are inconsistant
               (both up and down).

               In this situation, mcat can be either 0 or 3, depending
               on the value of vflag.  In either case, the placement of
               slurs cannot be inferred from this parameter.  The note
               in question might belong to a track that is "well behaved",
               i.e., not the "rogue track".  In this case, determining
               the type and placement of the slur will be straight-
               forward.  In the case where mcat = 0 (i.e. vflag = 1),
               it is likely that the rules for a single part may work
               fairly well.  In the case where mcat = 3 (i.e. vflag > 1),
               a number of difficult situations can arrise, such as a
               slur from a stem-up chord note (pass one) to a stem down
               note (pass two).  Such situation will have to be handled
               in a way that seems best under the particular circumstances.


     The MULTI_TRACK parameter will actually be combination of the
     multi-track flag and the value of mcat, according to the
     formula below:

         ts(.,MULTI_TRACK) = multi-track << 2 + mcat


        loop for a2 = 1 to 3
          loop for a3 = 1 to passnum         /* assume passnum = total # of passes
            loop for a4 = 1 to MAX_STAFF
              multichk(a2,a3,a4) = 0
            repeat
          repeat
        repeat
        loop for a1 = oldsct+1 to sct
          nodtype = ts(a1,TYPE)
          if nodtype <= NOTE_OR_REST
            a2 = nodtype + 2 / 3
            a3 = ts(a1,PASSNUM)
            a4 = ts(a1,STAFF_NUM) + 1        /* staff number
            a6 = multichk(a2,a3,a4)
            if rem <> 2
              a5 = bit(1,ts(a1,STEM_FLAGS)) + 1
              if a6 = 0 or a6 = 4
                multichk(a2,a3,a4) = a5
              else
                if a6 <> a5
                  multichk(a2,a3,a4) = 3
                end
              end
            else
              if a6 = 0
                multichk(a2,a3,a4) = 4        /* rest (stem direction unspecified)
              end
            end
          end
        repeat

        loop for a2 = 1 to 3               /* loop through note types i.e. reg,cue,grace
          loop for a4 = 1 to MAX_STAFF
            a5 = 0
            a6 = 0
            loop for a3 = 1 to passnum
              a7 = multichk(a2,a3,a4)
              if a7 = 3                    /* Case: multiple stem directions
                a6 = 100
              end
              if a7 > 0
                ++a5
                if a7 = 4
                  a8 = a3 + 1 / 2               /* set multichk to 1 for odd passnums, 2 for even
                  multichk(a2,a3,a4) = rem + 1  /*   for parts with only rests
                end
              end
            repeat
            if a6 = 100 and a5 > 1         /* Case: mult passes on staff and ambiguous stem dirs
              loop for a3 = 1 to passnum
                multichk(a2,a3,a4) = 3     /* all notes (for this type) on this staff have mt = 3
              repeat
            end
            if a5 = 1                      /* Case: single pass on this staff (for this note type)
              loop for a3 = 1 to passnum
                multichk(a2,a3,a4) = 0     /* all notes (for this type) on this staff have mt = 0
              repeat
            end
          repeat
        repeat

        loop for a1 = oldsct+1 to sct
          nodtype = ts(a1,TYPE)
          if nodtype <= NOTE_OR_REST
            a2 = nodtype + 2 / 3
            a3 = ts(a1,PASSNUM)
            a4 = ts(a1,STAFF_NUM) + 1      /* staff number
            a5 = multichk(a2,a3,a4) << 2
            ts(a1,MULTI_TRACK) = a5 + mcat
          end
        repeat
        if oldsct = 0
          firstsp = tfirstsp
        else

      Include tfirstsp in the spacing after previous completed bar

          if ts(oldsct,TYPE) <> BAR_LINE
            if ts(oldsct,SPACING) = 0
              putc There is something you didn't think about
              examine
              stop
            end
            ts(oldsct,SPACING) += tfirstsp
          else
            ts(oldsct,SPACING) += tfirstsp
          end
        end

      Compute the spn (spacing) parameter

        loop for a1 = oldsct+1 to sct
          if ts(a1,TYPE) = DIV_CHG and qflag = 1
            qflag = 2
          end
          if qflag = 0
            a5 = totdiv - 1
            a4 = ts(a1,DIV) - 1
            if a5 = a4
              spn = 6913
            else
              spn = 6912 / a5 * a4 + 1
            end
          else
            if qflag = 1
              a5 = mdiv - 1
              a4 = ts(a1,DIV) - 1
              if a5 = a4
                spn = 3457
              else
                spn = 3456 / a5 * a4 + 1
              end
            else
              a5 = totdiv - mdiv
              a4 = ts(a1,DIV) - mdiv
              if a5 = a4
                spn = 6913
              else
                spn = 3456 / a5 * a4 + 3457
              end
            end
          end
          ts(a1,SPN_NUM) = spn
        repeat

      We have a choice at this point whether to do extra calculations on
      the placement of notes, note-dots, and note-accidentals, or to wait
      to do this until the point when we process the entire array.  I think
      now is a good time to do this, because (1) I prefer to do work I think
      I know how to do earlier rather than later (you never know just what
      kinds of tasks you may have to do later, so why not get this one out
      of the way), and (2) the information gained in the this process might
      help us in the placement of slurs (which we will need to do first
      thing when we begin processing the entire array).

      Basically we are going to try to compute the following information for
      each "musical node".  The definition of a "musical node" is the set of
      one or more objects (chords + dots + accidentals) occuring on the same
      division number and which would, if possible, be placed in the same
      x-position on the staff.

        (1) the global x-offset.  This is the amount by which each object
              is displaced from the 0 x-position of all objects on this
              musical node.  I believe the global x-offset is always >= 0.
 
        (2) the local x-offset for note heads.  This is the amount by which
              each note head of a particular object is displaced from the
              x position of the object.

        (3) the location of rests on the staff (based on the position of
              other objects at this location).

        (4) the x and y offsets for any dot(s) which might follow each
              note head of a particular object.  Note: the y-position of
              an object which has more than one note head (chord) is
              the y position of the note head furthest from the note-end
              of the stem (i.e., therefore nearest to the beam end of
              the stem, if there is a beam).

        (5) the x offset (as measured to the left) of any accidental(s)
              which might precede each note head.


      I. How to store this information.

      (0) The grouping of elements in the ts(.,.) array into "musical
          nodes" can be determined by the space parameter "SPACING".
          The first array element of a "musical node" will have a
          non-zero space parameter, and any other element in the node
          will have a space parameter = 0.

      (1) The global x-offset can be stored in the GLOBAL_XOFF element
          of the ts(.,.) array.  If we further specify that the GLOBAL_XOFF
          element will be set to INT10000 * a1 (index of first note in the
          chord) + a2 (index of last note in chord), this will give us an
          easy way to determine the number of array elements (note heads)
          in the object (chord).

      (2) The local x-offset for note heads can be stored in the
          LOCAL_XOFF element of the ts(.,.) array.

      (3) The location of rests on the staff can be stored in the
          STAFFLOC element of the ts(.,.) array.

      (4) For the x and y offsets for any dots(s), we can use the DOT    (modified 12-24-96)
          element of the ts(.,.) array.  Up to this point, the DOT element
          could have five values: 0 = no dot; 1 = single dot; 3 = double dot;
          7 = triple dot; 15 = quadruple dot.  We need to preserve this
          information, which uses bits 0 through 3 of the integer.  Since
          the x offset is always positive, and the y offset may be positive
          or negative, we can construct a number which is x * INT10000 + y,
          shift it over 4 and OR it with the current value of DOT.

      (5) For the x offset of any accidental(s), we can use the AX
          element of the ts(.,.) array.  Up to this point, the AX element
          could have sixteen values: 0 to 15.  There is also the "silent"
          flag in bit 4 (value 16) which we need to preserve.  Altogether  (added 02/25/97)
          we need to preserve bits 0 through 4 of the integer.  Since
          the x offset (measured to the left) is always positive, we can
          simply shift this offset over 8 and OR with the current value
          of AX.

     II. Method of computation.

          The first task will be to compute the global and local x-offset
          for the note heads in each musical node.  We have a way of doing
          this, which we call pseudo-typesetting.  A concurrent task will
          be to compute the y location of rests in each musical node.

          The second task will be to compute the x and y offsets for any
          dots(s).  The method will be as follows (for each staff):

            (1) If there is only one note head on the staff, use the
                single note method for determining dot position.

                Otherwise, determine the x position for a "row of dots".
                This position will be to the right of the right-most
                note head on the stave.  (Note that the x-offset for
                each dot is the x position minus the global x-offset
                for each object).

            (2) Starting with the left-most objects in the "musical node"
                and moving to the right, set dot positions according to
                the following algorithm (keeping track of all previous
                dots for this stave):

                   Start with the note head furtherest from note-end of stem
                   If note on line,
                     if space above is free, put dot there
                     else put dot in first free space below
                   else
                     if space is free, put dot there
                     else put dot in first free space in reverse direction
                   end

          The third task will be to compute the x offsets for any
          accidental(s) for each note head.  The method will be as
          follows (for each staff):

            (1) Check the left-hand border from the typesetting operation.
                If there are any accidentals that could be set on right-
                shifted note heads, set these first, starting from the
                top down.  This defines column 1 of the accidentals.

                Otherwise, column one is the first free location to the
                left of the left-most note head.

            (2) For all remaining accidentals to set, start at the top
                of the group.  Make successive passes until all accidentals
                are set.

                (a) moving down, put in as many accidentals as possible
                    where the distance between eligible notes (delta) >=
                    vpar(6), with the caviat that you do not put an
                    accidental on the lower half of a second before the
                    upper half of a second (as you move down).

                (b) move to the left by the largest thickness of accidentals
                    just placed.  Decide on the direction to move for the
                    next pass and goto (a).  The new direction will be
                    down (again) if the previous pass hit the lowest remaining
                    accidental; otherwise, the new direction will be up.


          Good Luck with all of this!  If you get it right, you will have
          accomplished a good deal of the task of setting simultaneous
          notes!

          3-23-94:

          I am going to add another element to this process.  It turns out that
          this is the best time to determine whatever extra space is required
          for each object, based on the items previously typeset.  (We had been
          doing this later, but without the detailed information available in this
          part of the process, i.e. global-right boundaries, etc.).

          We start with the fact that the process below begins either after the
          initial setting of the clef, key and time, or after a controlling bar
          line.  In either case, we know the profile of "emptyspace" relative
          to the position we are about to put something.

          After processing each object, we need to be sure two things are done.

          (1) If there will be a need to shift the position of a node, the
          value of this shift (positive or negative) needs to be stored in the
          array element: NODE_SHIFT.

          (2) The values of emptyspace need to be updated.

        olda1 = 0

        loop for a1 = oldsct+1 to sct
          nodtype = ts(a1,TYPE)
          if nodtype > NOTE_OR_REST

        A. Figure out space for Bar Line

            if nodtype = BAR_LINE
              a5 = 1000000
              loop for a3 = 1 to MAX_STAFF
                loop for a4 = 1 to 45
                  if emptyspace(a3,a4) < a5
                    a5 = emptyspace(a3,a4)
                  end
                repeat
              repeat
              a6 = mindist - hpar(82) - a5
    Task (1)
              if a6 > 0
                ts(a1,NODE_SHIFT) = a6
              end
    Task (2)
              a5 = ts(a1,SPACING) - hpar(93)
              loop for a4 = 1 to MAX_STAFF
                loop for a3 = 1 to 45
                  emptyspace(a4,a3) = a5
                repeat
              repeat
              goto WWWW
            end

        B. Figure out space for Clef change

            if nodtype = CLEF_CHG
              a3 = ts(a1,STAFF_NUM) + 1         /* staff number

       Check to see if we can "backup" the node position

              a5 = 1000000
              loop for a4 = 1 to 45
                if emptyspace(a3,a4) < a5
                  a5 = emptyspace(a3,a4)        /* minimum emptyspace on this staff
                end
              repeat
    Task (1)
              if a5 > ts(a1,SPACING) >> 1
                a4 = a5 * 2 / 3
                a7 = ts(a1,SPACING)
                c2 = 0
                loop for c1 = a1+1 to sct          /* check if following note has accidentals
                  if ts(c1,DIV) <> ts(a1,DIV)
                    goto HJKO
                  end
                  a6 = ts(c1,TYPE)
                  if a6 > FIGURES
                    goto HJKO
                  end
                  if a6 <> REST and a6 <> CUE_REST and a6 <> FIGURES
                    if ts(c1,STAFF_NUM) = ts(a1,STAFF_NUM)
                      a6 = ts(c1,AX) & 0x1f
                      if a6 > 0 and hpar(a6) > c2
                      if a6 < 0x10 and a6 > 0 and hpar(a6) > c2   /* Code modified 02/25/97
                        c2 = hpar(a6)
                      end
                    end
                  end
                repeat
HJKO:
                a7 += c2
                if a4 > a7
                  a4 = a7
                end
                ts(a1,NODE_SHIFT) = 0 - a4    /* negative shift
              else
                a6 = mindist - hpar(82) - a5
                if a6 > 0
                  ts(a1,NODE_SHIFT) = a6
                end
              end
    Task (2)
              a5 = ts(a1,SPACING) - a4          /* amount by position really advanced
              a7 = hpar(86)
              if z > 128
                a7 = a7 * 7 / 10                /* use to be 8 / 10
              end
              a7 = ts(a1,SPACING) - a7          /* empty space after clef sign
              loop for a4 = 1 to MAX_STAFF
                if a4 = a3
                  loop for a6 = 1 to 45
                    emptyspace(a4,a6) = a7
                  repeat
                else
                  loop for a6 = 1 to 45
                    emptyspace(a4,a6) += a5
                  repeat
                end
              repeat
              goto WWWW
            end

        C. Figure out space for Time change

            if nodtype = METER_CHG
              a5 = 1000000
              loop for a3 = 1 to MAX_STAFF
                loop for a4 = 1 to 45
                  if emptyspace(a3,a4) < a5
                    a5 = emptyspace(a3,a4)
                  end
                repeat
              repeat
              a6 = hpar(12) - a5
    Task (1)
              if a6 > 0
                ts(a1,NODE_SHIFT) = a6
              end
    Task (2)
              loop for a4 = 1 to MAX_STAFF
                loop for a3 = 1 to 45
                  emptyspace(a4,a3) = min_space            /* replaces hpar(29)   11/19/07
                repeat
              repeat
              goto WWWW
            end

        D. Figure out space for Key change

            if nodtype = AX_CHG
              a5 = 1000000
              loop for a3 = 1 to MAX_STAFF
                loop for a4 = 1 to 45
                  if emptyspace(a3,a4) < a5
                    a5 = emptyspace(a3,a4)
                  end
                repeat
              repeat
              a6 = hpar(37) - hpar(93) - a5
    Task (1)
              if a6 > 0
                ts(a1,NODE_SHIFT) = a6
              end
    Task (2)
              loop for a4 = 1 to MAX_STAFF
                loop for a3 = 1 to 45
                  emptyspace(a4,a3) = hpar(12)
                repeat
              repeat
              goto WWWW
            end

        E. Figure out space for Signs, Words and Marks which are Objects
 
            if nodtype = SIGN or nodtype = WORDS or nodtype = MARK
              ts(a1,NODE_SHIFT) = 0
              goto WWWW
            end

        F. Figure out space for Figures
 
            if nodtype = FIGURES
              c3  = FIG_DATA
              c11 = 0
              c14 = 0                         /* Flag for preceding accidentals on figures
              loop for c2 = 1 to ts(a1,NUMBER_OF_FIG)
                c12 = 0

     Code added 11/16/03 to deal with parentheses around figures

                c6 = ts(a1,c3)
                c13 = 0                       /* Flag for parentheses around figures
                if c6 > 1000
                  c6 -= 1000
                  if c6 > 1000                /* large parentheses
                    c6 = c6 / 1000
                    c6 = rem
                    c13 = hpar(138) + hpar(139)
                  else                        /* small parentheses
                    c13 = hpar(136) + hpar(137)
                  end
                end



     And this code rewritten 11/16/03

                if c6 > 0
                  temp = chr(c6+28)
                  if "1389" con temp          /* case: accidental x,#,f,n
                    c4 = ts(a1,c3+1)
                    if c4 > 0                 /* sub-case: accidental followed by figure
                      c14 = hpar(c4+47)       /* result: set flag for preceding accidental
                      if c4 < 20                    /* figure
                        if c4 < 10
                          c12 = hpar(66)
                        else
                          c12 = hpar(66) << 1
                        end
                      else
                        c12 = hpar(c4+67)
                      end
                    else
                      c12 = hpar(c6+47)       /* 20 <= c6 <= 30 --> hpar(67) to hpar(77)
                    end
                  else
                    if c6 < 20                /* case: figure
                      if c6 < 10
                        c12 = hpar(66)
                      else
                        c12 = hpar(66) << 1
                      end
                      c4 = ts(a1,c3+1)
                      if c4 > 0               /* accidental following number
                        temp = chr(c4+28)
                        if "01389" con temp
                          c12 += hpar(c4+47)
                        end
                      end
                    else                      /* cases: isolated +,2+,4+,5+,6\,7\,-
                      c12 += hpar(c6+47)
                    end
                  end
                end

                c12 += c13                    /* Adding space for parentheses 11/16/03
                if c12 > c11
                  c11 = c12
                end
                c3 += 3
              repeat

              c11 += c14                      /* Adding space for pre-accidentals 11/16/03
              c11 += hpar(75)                 /* free space = width of natural

              if ts(a1,MIN_FIG_SPAC) < c11
                ts(a1,MIN_FIG_SPAC) = c11
              end
              if ts(a1,FIG_SPACE) > 0 and ts(a1,FIG_SPACE) < c11
                ts(a1,FIG_SPACE) = c11
              end
              a4 = ts(a1,FIG_SPACE)
              ts(a1,NODE_SHIFT) = 0
              if a4 > 0
                loop for a3 = 1 to MAX_STAFF
                  loop for a2 = 1 to 45
                    emptyspace(a3,a2) += a4
                  repeat
                repeat
              end
              goto WWWW
            end
            goto WWWW
          end

      PROCESSING NOTES AND RESTS NOW

          npasses = 1
          a3 = 1
          if a1 = sct              /* added 01-31-97
            a2 = a1
            pitchcnt(1) = 1
            goto X1
          end
          loop for a2 = a1+1 to sct
            if ts(a2,SPACING) <> 0
              --a2
              pitchcnt(npasses) = a3
              goto X1
            end
            if ts(a2,TYPE) > NOTE_OR_REST
              --a2
              pitchcnt(npasses) = a3
              goto X1
            end
            if nodtype = GR_NOTE
              if ts(a2,TYPE) = XGR_NOTE
                ++a3
              else
                pitchcnt(npasses) = a3
                a3 = 1
                ++npasses
              end
            else
              if ts(a2,TYPE) = XNOTE or ts(a2,TYPE) = XCUE_NOTE
                ++a3
              else
                pitchcnt(npasses) = a3
                a3 = 1
                ++npasses
              end
            end
          repeat
X1:

     a2          = index to last element in node
     npasses     = number of passes
     pitchcnt(.) = size of chord for each pass

          if a1 = a2     /* Simple (and most common) case:  single element, a2 = a1

          if ts(a1,MULTI_TRACK) < 4 and a1 = a2

            a3 = ts(a1,STAFF_NUM) + 1         /* staff number
            c1 = a1
            passnum = ts(c1,PASSNUM)
            ntype = ts(c1,NTYPE)
            ntype = ts(c1,NTYPE) & 0xff           /* new 10/15/07
            stem = bit(1,ts(c1,STEM_FLAGS))
            if nodtype <= REST
              passtype = REG
              passsize = FULLSIZE
              if bit(16,ts(c1,SUBFLAG_1)) = 1
                passsize = CUESIZE                /* EXPERIMENT  06-24-94
              end
            else
              passsize = CUESIZE
              if nodtype <= CUE_REST
                passtype = CUE
              else
                passtype = GRACE
              end
            end

      a) rests

            if nodtype = REST or nodtype = CUE_REST
              if scr_flag = 1
                if ts(c1,CLAVE) = 200                  /* "silent" rest
                  ts(c1,STAFFLOC) = 0
                  ts(c1,OBY) = 0
                  ts(c1,DOT) = 0
                  ts(a1,NODE_SHIFT) = 0
                  goto MMMMM
                end
              end

              if nodtype = REST
                c8 = vpar(4)
              else
                c8 = vpar(2)
              end
              if ts(c1,STAFFLOC) = 1
                c8 = vpar(4)
              end
              ts(c1,STAFFLOC) = c8
              ts(c1,OBY) = c8
              if ts(c1,DOT) > 0
                c4 = 0            /* additions to "eighth rest"
                c2 = 0            /* y shift down for starting rests
                c6 = 0            /* extra height of dot  (negative shift)
                if ntype <= SIXTEENTH
                  c6 = notesize
                  c4 = EIGHTH - ntype
                  c2 = notesize
                  if ntype < THIRTY_SECOND
                    c2 = THIRTY_SECOND - ntype * notesize + c2
                  end
                end
                if ntype > QUARTER
                  c3 = hpar(30)
                else
                  c3 = c4 * hpar(54) + hpar(31)
                  c6 *= c4
                end
                if passsize = CUESIZE
                  c3 = c3 * 8 / 10
                end
                c7 = c3

     Minor code modification 04/19/08

                if ntype <= SIXTEENTH
                  c3 -= hpar(54)
                end

                c6 += vpar(1) /* shift to space   OK 4-21-95
             /* c3 is the x shift to the dot(s)
                c2 -= c6      /* final y offset
                c9 = c2
             /* x * INT10000 + y, shift it over 4 and OR it with DOT   (code modified 12-24-96)
                c3 *= INT10000
                c3 += c2
                c3 <<= 4                                         /*    (code modified 12-24-96)
                ts(c1,DOT) |= c3
              else
                c7 = 0
                c9 = 0
              end
    Task (1)
              a5 = 1000000
              loop for a4 = 1 to 45
                if emptyspace(a3,a4) < a5
                  a5 = emptyspace(a3,a4)        /* minimum emptyspace on this staff
                end
              repeat

              a6 = mindist - hpar(82) - a5
              if a6 > 0
                ts(a1,NODE_SHIFT) = a6
              end
    Task (2)
              loop for a6 = 1 to 45
                gr(a3,a6) = -200
              repeat

              if ts(c1,CLAVE) < 200 or scr_flag = 0
                perform rest_occupy_space (c8,a3)     /* ntype is read directly
              end

              if ts(c1,DOT) > 0
                c8 += c9
                if c8 >= 0
                  c8 = 2 * c8 + 1 / vpar(2)
                else
                  c8 = 2 * c8 - 1 / vpar(2)
                end
                c8 = 23 - c8
                c7 += hpar(80)
                if ts(c1,DOT) & 0x0e > 0            /* code modified 12-24-96
                  if ts(c1,DOT) & 0x02 > 0
                    c7 += hpar(91)                    /* extra shift to second dot
                  end
                  if ts(c1,DOT) & 0x04 > 0
                    c7 += hpar(91)                    /* extra shift to third dot
                  end
                  if ts(c1,DOT) & 0x08 > 0
                    c7 += hpar(91)                    /* extra shift to fourth dot
                  end
                end
                loop for a6 = c8 - 1 to c8 + 1
                  gr(a3,a6) += c7
                repeat
              end
              c10 = ts(c1,SPACING)
              loop for c11 = 1 to MAX_STAFF
                if c11 = a3
                  loop for c6 = 1 to 45
                    if gr(c11,c6) = -200
                      emptyspace(c11,c6) += c10
                    else
                      emptyspace(c11,c6) = c10 - gr(c11,c6)
                    end
                  repeat
                else
                  loop for c6 = 1 to 45
                    emptyspace(c11,c6) += c10
                  repeat
                end
              repeat
            else

      b) notes

              repeater_case      = 0
              ts(c1,LOCAL_XOFF)  = 0
              ts(c1,GLOBAL_XOFF) = 0

   Technically, this code must also appear here, although it is highly unlikely
   that anyone would want to shift a single note on a stave from its primary position.

                               All New code 05/02/03

        At this point, we need to see if the note object position has been modified
        "absolutely" by a print suggestion.  If this is the case, we need to make the
        adjustment here, AND, elimate the suggestion from the tsr string.

              c6 = ts(c1,TSR_POINT)
              c7 = ors(tsr(c6){2})
              if bit(0,c7) = 1
                px = ors(tsr(c6){3})
                if px > 0
                  px = px - 128 * notesize / 10
                  pxx = c7 & 0x02 >> 1
                  if pxx = 1
                    ts(c1,GLOBAL_XOFF) = px
                    tsr(c6){3} = chr(0)         /* here is where suggestion is zerod out
                  end
                end
              end

        End of new code 05/02/03

              c6 = ts(c1,STAFFLOC) / vpar(1)
              c6 = ts(c1,STAFFLOC) + vpar20 * 2 + 1 / vpar(2) - 20

              if ts(c1,DOT) > 0
                if ntype > HALF
                  c3 = hpar(32)
                else
                  c3 = hpar(33)
                end
                c10 = ts(c1,STAFFLOC) / notesize
                c10 = rem                 /* c10 = 0 means note on line
                if stem = UP
                  if ts(c1,BEAM_FLAG) = NO_BEAM and ts(c1,NTYPE) < QUARTER
                    c3 += hpar(27)
                    if c10 <> 0
                      c3 -= hpar(34)
                    end
                  end
                end
                c8 = c3

*    if dot is on staff line, c10 = 0
                if c10 = 0
                  c2 = 0 - vpar(12)
           /* lower dot if more than one track and stem is down
                  if bit(3,ts(c1,MULTI_TRACK)) = 1
                    if stem = DOWN
                      c2 = vpar(12)
                    end
                  end
                  c3 -= hpar(34)
                else
                  c2 = 0
                end

                if ntype > HALF
                  c8 -= hpar(32)
                else
                  c8 -= hpar(33)
                end
                if c8 < 3
                  c8 = 0
                end

                if passsize = CUESIZE
                  c3 = c3 * 8 / 10
                  c8 = c8 * 8 / 10
                end
             /* c3 = x shift
             /* c2 = y offset

                c7 = ts(c1,DOT) & 0x0f
                c7 = int("1.2...3.......4"{c7})     /* convert to SCORE code
                c7 *= 10
                if c2 > 0
                  c7 += 100
                end

                c8 = c8 * 30 / scr_qwidth          /* 100ths part of P9
                if c8 > 99
                  c8 = 99
                end
                c7 = c7 << 8 + c8
                ts(c1,AUG_DOTS) = c7

             /* x * INT10000 + y, shift it over 2 and OR it with DOT   (code modified 12-24-96)
                c7 = c3
                c8 = c2
                c3 *= INT10000
                c3 += c2
                c3 <<= 4                                            /*  code modified 12-24-96
                ts(c1,DOT) |= c3
              end

        Delete this code from this location.  Add this task below
           where limits for accidentals are established

              if ts(c1,AX) > 0
                c5 = ts(c1,AX) & 0x0f
                c7 = hpar(c5)
            /* shift this offset over 4 and OR with AX
                c7 <<= 4
                ts(c1,AX) |= c7
              end


    Task (1)
              loop for c10 = 1 to 45
                gl(a3,c10) = 200
                pseudo_gl(a3,c10) = 200
                gr(a3,c10) = -200
              repeat
              c6 = 23 - c6

              if c6 > 45 or c6 < 1
                putc
                putc               FAULT CONDITION
                putc
                putc Note out of staff range.  Please check clef.
                putc
                putc Program Halted
                putc
                stop
              end
        /* Determine thickness of note: c11
              if ntype <= HALF or ntype = SLASH8
                c11 = hpar(82)
              else
                if ntype >= BREVE
                  c11 = hpar(84)
                else
                  c11 = hpar(83)
                end
              end
              if passsize = CUESIZE
                c11 = c11 * 8 / 10
              end
        /* Put in limits of note head
              gl(a3,c6+1) = hpar(95)
              pseudo_gl(a3,c6+1) = 0
              gl(a3,c6)   = 0
              gr(a3,c6+1) = c11
              gr(a3,c6)   = c11 - hpar(95)

              if ntype < WHOLE
        /* Determine length of stem: c10
                if ntype > EIGHTH
                  c10 = 8                          /* length of stem
                else
                  c10 = 7
                  if ntype < EIGHTH
                    c10 += EIGHTH - ntype
                  end
                end
                if passsize = CUESIZE
                  c10 = c10 * 8 / 10
                end
                if ts(c1,BEAM_FLAG) = NO_BEAM and ts(c1,BEAM_CODE) > 0
                  repeater_case = 1
                  c13 = ts(c1,BEAM_CODE) / 10
                  loop while c13 > 0
                    c13 /= 10
                    c10 += 2
                  repeat
                end
        /* Determine thickness of stem: c12
                if ts(c1,BEAM_FLAG) = NO_BEAM and ntype < QUARTER
                  c12 = hpar(26)
                  if passsize = CUESIZE
                    c12 = c12 * 8 / 10
                  end
                else
                  if stem = UP
                    c12 = 0
                  else
                    c12 = hpar(90)
                  end
                end
        /* Put in limits of gl(.,.) and gr(.,.) for stem

      06/04/08  Fixing case where there are no-beam repeaters

                if stem = UP
                  c13 = c6 + c10
                  if c13 > 45
                    c13 = 45
                  end
                  gr(a3,c6+1) = c11 + c12

                  loop for c14 = c6 + 2 to c6 + 3   /* No repeaters near note head
                    gr(a3,c14) = c11 + c12
                    gl(a3,c14) = c11 - hpar(90)
                  repeat

                  if repeater_case = 1
                    c15 = hpar(98) + hpar(90)
                    if ntype >= QUARTER
                      c12 += hpar(98)
                    end
                  else
                    c15 = hpar(90)
                  end
                  loop for c14 = c6 + 4 to c13      /* 06/04/08 changing c6 + 2 to c6 + 4
                    gr(a3,c14) = c11 + c12
                    gl(a3,c14) = c11 - c15
                  repeat
                else
                  c13 = c6 - c10
                  if c13 < 1
                    c13 = 1
                  end

                  loop for c14 = c6 - 2 to c6 - 1   /* No repeaters near note head
                    gr(a3,c14) = c12
                    gl(a3,c14) = 0
                  repeat

                  if repeater_case = 1
                    c11 = hpar(98)
                  else
                    c11 = 0
                  end
                  loop for c14 = c13 to c6 - 3      /* 06/04/08 changing c6 - 1 to c6 - 3
                    gr(a3,c14) = c12
                    gl(a3,c14) = 0 - c11
                  repeat
                end
              end

           Put in limits of for accidentals
                and store location of accidental

              if ts(c1,AX) > 0
                c5 = ts(c1,AX) & 0x0f
                c7 = passsize
                perform place_accidental (a3,c6,c5,c7)  /* returns c7 = negative offset

       Note: place_accidental operates over the entire simultaneity, and therefore
             returns an absolute (negative, left <--) shift relative to the
             undisplaced musical node.  This is exactly the information that
             SCORE wants in parameter P5, fractional part.  Note that SCORE assigns
             the fractional value .00 to the normal position of the accidental,
             which in the MUSEDATA I-file is shifted.

             One extra twist:  SCORE provides no direct way a representing
             natural-sharp, and natural-flat in a notehead.  We will have to set
             the P5 parameter as if the natural were not there and indicate the
             relative position where a natural will have to be set using a
             CODE-9 item.

             Since the code that determines P5 and the CODE-9 item must execute
             every time place_accidental runs, I am going to try to put this
             code inside the place_accidental procedure.  There will be a need
             to return data in a second parameter.  I propose using the third
             parameter in the list.
 
                ts(c1,AX_DISP) = c5  /* capture this parameter, returned from place_accidental

            /* shift the offset over 8 and OR with AX
                c7 = 0 - c7                             /* we store positive value
                c7 <<= 8               /* 02/25/97 shift changed from 4 to 8
                ts(c1,AX) |= c7
              end

        Adjust the gr(.,.) array to accommodate space for dots
            (added 04/04/94)

              c8 = ts(a1,STAFF_NUM) + 1                    /* staff number
              c3 = ts(a1,DOT)
              if c3 > 0                                    /* code modified 12-24-96
                c4 = c3 & 0x0f               /* dot flag   /* 12-24-96
                c3 >>= 4                                   /* 12-24-96
                c5 = c3 / INT10000           /* x offset
                c6 = rem                     /* y offset
                if c6 > INT10000 >> 1
                  c6 -= INT10000
                  ++c5
                end
                c6 = c6 + vpar(8) - 1 / vpar(1) - 7
                c6 = c6 + vpar(8) * 2 - 1 / vpar(2) - 7

                c6 = 0 - ts(a1,STAFFLOC) / vpar(1) + 23 - c6
                c10 = ts(a1,STAFFLOC) + vpar20 * 2 + 1 / vpar(2) - 20
                c6 = 23 - c10 - c6

                c5 += hpar(80)
                if c4 > 1                                  /* modified 12-24-96
                  c5 += hpar(91)                         /* second dot
                  if c4 > 4
                    c5 += hpar(91)                         /* third dot
                  end
                  if c4 > 8
                    c5 += hpar(91)                         /* fourth dot
                  end
                end
                if c6 < 46 and c6 > 0
                  gr(c8,c6) = c5
                end
              end

        /* Calculate NODE_SHIFT
              c10 = 0
              if c1 = 1 or ts(c1-1,TYPE) < CUE_NOTE
                c6 = min_space            /* replaces hpar(29)   11/19/07
              else
                c6 = min_space / 2        /* replaces hapr(29) / 2  11/19/07
              end
              loop for c11 = 1 to 45
                if gl(a3,c11) > pseudo_gl(a3,c11)
                  gl(a3,c11) = pseudo_gl(a3,c11)
                end
                c12 = c6       - gl(a3,c11) - emptyspace(a3,c11) /* should be negative
                if c12 > c10                                     /* most of the time
                  c10 = c12
                end
              repeat
before02/25/97if ts(c1,AX) > 0 and ts(c1,SPACING) = mindist and c10 < hpar(94)
              if (ts(c1,AX) & 0x0f) > 0 and ts(c1,SPACING) = mindist and c10 < hpar(94)
                c10 = hpar(94)
              end
              if c10 > 0
                ts(c1,NODE_SHIFT) = c10
              end
    Task (2)
              c10 = ts(c1,SPACING)
              loop for c11 = 1 to MAX_STAFF
                if c11 = a3
                  loop for c6 = 1 to 45
                    if gr(c11,c6) = -200
                      emptyspace(c11,c6) += c10
                    else
                      emptyspace(c11,c6) = c10 - gr(c11,c6)
                    end
                  repeat
                else
                  loop for c6 = 1 to 45
                    emptyspace(c11,c6) += c10
                  repeat
                end
              repeat
            end
          else

  ╔════════════════════════════════════════════════════════════════╗
                                                                  
     Here is where you deal with chords and with multiple passes  
                                                                  
  ╚════════════════════════════════════════════════════════════════╝

                        ┌──────────────────────┐
                        │ D I S C U S S I O N  │
                        └──────────────────────┘

        To start with, a major difference between the single note version
    and this multiple note version is the placement of (1) the note heads
    in chords and (2) the chord groups, themselves.  The major problem is
    to determine the x-offset for each note in a chord and the x-offset for
    each chord group.  Once this information is known, it will then be
    possible to typeset the various entities in a manner somewhat similar
    to the case of the single note version above.

        The x placement of all of the elements of a multiple note node
    requires consideration of all of the elements; i.e., they cannot be
    simply put down in a serial fashion.  Therefore, we must do a pseudo-
    typesetting of the elements, and from this extract the x-offsets we
    need to do the real job.  I note that set array elements 13 and 19
    are free at this point, so we can use them to store local x-offset and
    global x-offset, respectively (LOCAL_XOFF, GLOBAL_XOFF).

        Also, the vertical placement of rests must be taken into
    consideration.  There is no definite parameter in the stage2 source
    file that tells us were to locate rests vertically.  We have two
    indirect parameters available: (1) the pass number, based on the
    the order of encoding the material, and (2) the optional track
    number.  I would favor using the pass number at this point.  Where
    the maximum pass number is 2, rests could be located "high" and
    "low" for passes 1 and 2, respectively; where the maximum pass number
    is 3, rests could be located "high", "medium" and "low", etc.  In the
    case of the grand staff (two or more staves), these locations could
    be refined to reflect the staff on which the rests are being put.


    ╔═════════════════════════════════════════════════════╗
                                                      
             (A) pseudo-typeset the notes             
                                                      
    ╚═════════════════════════════════════════════════════╝


                ┌─────────────────────────┐
                │   construct note data   │
                └─────────────────────────┘
 
    ndata(1) = pass number (set to 0, after chord is typeset)
    ndata(2) = stem flag:
                  bit 0: direction    0 = up, 1 = down
                  bit 1: repeater     0 = none, 1 = present
               bits 2-4: flag flag    0 = no flag
                                      1 = eighth flag
                                      2 = sixteenth flag
                                      3 = 32nd flag
                                      4 = 64th flag
                                      5 = 128th flag
                                      6 = 256th flag

    ndata(3)  = color  0 = black, 1 = half, 2 = whole, 3 = breve
    ndata(4)  = dot    0 = none, 1 = dot
    ndata(5)  = pitch
    ndata(6)  = position in chord (from note end of stem)
    ndata(7)  = final x-position of this pitch within chord
    ndata(8)  = pass number
    ndata(9)  = staff number
    ndata(10) = note size (full size vs. que size)
    ndata(11) = ntype
    pcnt     = total number of notes (and rests)
 
#define  PS_PASS    1
#define  PS_STEM    2
#define  PS_COLOR   3
#define  PS_DOT     4
#define  PS_PITCH   5
#define  PS_RANK    6
#define  PS_XPOS    7
#define  PS_PASS2   8
#define  PS_STAFF   9
#define  PS_NSIZE  10
#define  PS_NTYPE  11

            loop for i = 1 to 45     /* initialize right and left boundaries
              gr(1,i) = -200
              gr(2,i) = -200
              pseudo_gr(1,i) = -200
              pseudo_gr(2,i) = -200
              pseudo_gl(1,i) = 200
              pseudo_gl(2,i) = 200
              gl(1,i) = 200
              gl(2,i) = 200
            repeat

            pcnt = 0
            putc Note data array
            putc ───────────────────────────
            c1 = a1
            ps_passcount(1) = 0
            ps_passcount(2) = 0

            loop for thispass = 1 to npasses
              c2 = ts(c1,STAFF_NUM) + 1           /* staff number
              ++ps_passcount(c2)
              c2 = 0
              loop for c3 = 1 to pitchcnt(thispass)
                ++pcnt
                ndata(pcnt,PS_PASS2) = thispass
                ndata(pcnt,PS_PASS)  = thispass
                ndata(pcnt,PS_STEM)  = bit(1,ts(c1,STEM_FLAGS))
                if c3 = 1 and ts(c1,BEAM_FLAG) = NO_BEAM
                  if ts(c1,BEAM_CODE) > 0
                    ndata(pcnt,PS_STEM) += 2
                  end
                  if ts(c1,NTYPE) < QUARTER
                    c4 = QUARTER - ts(c1,NTYPE) << 2
                    ndata(pcnt,PS_STEM) += c4
                  end
                end

                if ts(c1,CLAVE) < 100           /* note
                  if ts(c1,NTYPE) < HALF
                    ndata(pcnt, PS_COLOR) = 0
                  else
                    ndata(pcnt,PS_COLOR) = ts(c1,NTYPE) - 7
                  end
                else
                  ndata(pcnt,PS_COLOR) = ts(c1,NTYPE)
                  ndata(pcnt,PS_COLOR) = ts(c1,NTYPE) & 0xff    /* new 10/15/07
                end
                ndata(pcnt,PS_NTYPE) = ts(c1,NTYPE)
                ndata(pcnt,PS_NTYPE) = ts(c1,NTYPE) & 0xff      /* new 10/15/07
                if ts(c1,TYPE) <= REST
                  ndata(pcnt,PS_NSIZE) = bit(16,ts(c1,SUBFLAG_1))
                else
                  ndata(pcnt,PS_NSIZE) = CUESIZE
                end

                ndata(pcnt,PS_DOT)   = ts(c1,DOT)
                if ts(c1,CLAVE) < 100           /* note
                  ndata(pcnt,PS_PITCH) = 0 - ts(c1,STAFFLOC) / vpar(1) + 23
                  c10 = ts(c1,STAFFLOC) + vpar20 * 2 + 1 / vpar(2) - 20
                  ndata(pcnt,PS_PITCH) = 23 - c10
                else
                  ndata(pcnt,PS_PITCH) = 100    /* rest
                end
                ndata(pcnt,PS_XPOS)  = 0
                ndata(pcnt,PS_STAFF) = ts(c1,STAFF_NUM)
                ++c1
      compute horizontal placement of notes for down stems (on the fly)
                if bit(0,ndata(pcnt,PS_STEM)) = DOWN and c3 > 1
                  c4 = ndata(pcnt-1,PS_PITCH) - ndata(pcnt,PS_PITCH)
                  if c4 = 1
                    if c2 = 0
                      ndata(pcnt,PS_XPOS) = -1
                      c2 = 1
                    else
                      c2 = 0
                    end
                  else
                    c2 = 0
                  end
                end
      rank the notes in a chord
                if bit(0,ndata(pcnt,PS_STEM)) = UP
                  ndata(pcnt,PS_RANK) = pitchcnt(thispass) + 1 - c3
                else
                  ndata(pcnt,PS_RANK) = c3
                end
              repeat
      compute horizontal placement of notes for up stems
              if pcnt > 0 and bit(0,ndata(pcnt,PS_STEM)) = UP and pitchcnt(thispass) > 1
                c5 = pcnt
                c2 = 0
                loop for c3 = 2 to pitchcnt(thispass)
                  c4 = ndata(c5-1,PS_PITCH) - ndata(c5,PS_PITCH)
                  if c4 = 1 and c2 = 0
                    ndata(c5-1,PS_XPOS) = 1
                    c2 = 1
                  else
                    c2 = 0
                  end
                  --c5
                repeat
              end
              c2 = pcnt - pitchcnt(thispass) + 1
              loop for c3 = c2 to pcnt
                loop for c5 = 1 to 7
                  putc .w4 ~ndata(c3,c5) ...
                repeat
                putc
              repeat
            repeat


      determine all clashes between chords

            loop for c2 = 1 to npasses
              loop for c3 = 1 to npasses
                clashes(c2,c3) = 0
              repeat
            repeat

            loop for c2 = 1 to pcnt - 1
              loop for c3 = c2+1 to pcnt
                c4 = ndata(c2,PS_PASS)
                c5 = ndata(c3,PS_PASS)
                if c4 <> c5 and ndata(c2,PS_STAFF) = ndata(c3,PS_STAFF)
                  if ndata(c2,PS_XPOS) = 0 and ndata(c3,PS_XPOS) = 0
                    if ndata(c2,PS_PITCH) < 100
                      c6 = ndata(c2,PS_PITCH) - ndata(c3,PS_PITCH)
                      if c6 = 0                                     /* same pitch
                        if bit(0,ndata(c2,PS_STEM)) = bit(0,ndata(c3,PS_STEM))
                          clashes(c4,c5) = 1
                          clashes(c5,c4) = 1
                          goto PS_D2
                        end
                        if ndata(c2,PS_COLOR) <> ndata(c3,PS_COLOR)
                          clashes(c4,c5) = 1
                          clashes(c5,c4) = 1
                          goto PS_D2
                        end
                        if ndata(c2,PS_NSIZE) <> ndata(c3,PS_NSIZE)
                          clashes(c4,c5) = 1
                          clashes(c5,c4) = 1
                          goto PS_D2
                        end
#if DOT_DIFFERENCE

      12/24/05  This optional code is now controlled by dot_difference_flag

                        if dot_difference_flag = 1
                          if ndata(c2,PS_DOT) <> ndata(c3,PS_DOT)
                            clashes(c4,c5) = 1
                            clashes(c5,c4) = 1
                            goto PS_D2
                          end
                        end

#endif
                        if ndata(c2,PS_RANK) * ndata(c3,PS_RANK) <> 1
                          clashes(c4,c5) = 1
                          clashes(c5,c4) = 1
                          goto PS_D2
                        end
 
            We must now ask the question: are all notes of first chord either
               equal/above all notes of second chord, or equal/below all notes
               of second chord.

                        c10 = 0
                        loop for c9 = 1 to pcnt
                          if ndata(c9,PS_PASS) = ndata(c2,PS_PASS)
                            if ndata(c9,PS_PITCH) <> ndata(c2,PS_PITCH)
                              if ndata(c9,PS_PITCH) > ndata(c2,PS_PITCH)
                                if c10 = -1
                                  c10 = 1000
                                else
                                  c10 = 1
                                end
                              end
                              if ndata(c9,PS_PITCH) < ndata(c2,PS_PITCH)
                                if c10 = 1
                                  c10 = 1000
                                else
                                  c10 = -1
                                end
                              end
                            end
                          end
                        repeat
                        if c10 = 1000
                          clashes(c4,c5) = 1
                          clashes(c5,c4) = 1
                          goto PS_D2
                        end
                        loop for c9 = 1 to pcnt
                          if ndata(c9,PS_PASS) = ndata(c3,PS_PASS)
                            if ndata(c9,PS_PITCH) <> ndata(c3,PS_PITCH)
                              if ndata(c9,PS_PITCH) > ndata(c3,PS_PITCH)
                                if c10 = 0
                                  c10 = -1
                                end
                                if c10 = 1
                                  c10 = 1000
                                end
                              end
                              if ndata(c9,PS_PITCH) < ndata(c3,PS_PITCH)
                                if c10 = 0
                                  c10 = 1
                                end
                                if c10 = -1
                                  c10 = 1000
                                end
                              end
                            end
                          end
                        repeat
                        if c10 = 1000
                          clashes(c4,c5) = 1
                          clashes(c5,c4) = 1
                          goto PS_D2
                        end
                        clashes(c4,c5) = 2
                        clashes(c5,c4) = 2
                        goto PS_D2
                      end
                      if c6 = 1 or c6 = -1
                        clashes(c4,c5) = 1
                        clashes(c5,c4) = 1
                      end
                    end
                  end
                end
PS_D2:
              repeat
            repeat

      typeset all groups of chords for which there are no clashes

            loop for c2 = 1 to npasses
              tgroup(c2) = 0
            repeat
            ntgroups = 0
            loop for c2 = 1 to npasses
              c5 = 0
              loop for c3 = c2+1 to npasses
                if clashes(c2,c3) <> 1 and tgroup(c3) = 0
                  if c5 = 0
                    ++ntgroups
                    c5 = 1
                    tgroup(c2) = ntgroups
                    tgroup(c3) = ntgroups
                  else
                    loop for c4 = c2+1 to c3-1
                      if tgroup(c4) = ntgroups and clashes(c4,c3) = 1
                        c4 = 1000
                      end
                    repeat
                    if c4 <> 1000
                      tgroup(c3) = ntgroups
                    end
                  end
                end
              repeat
            repeat

            loop for c3 = 1 to npasses
              putc tgroup(~c3 ) = ~tgroup(c3)
            repeat

            c10 = 0                        /* initialize right-hand chord boundary

            loop for c3 = 1 to ntgroups    /* number of typeset groups

      typeset chords

              loop for c4 = 1 to 2    /* typeset stem down first
                c5 = 2 - c4
PS_CC:          c6 = 0
                c7 = 0
                c15 = 0
                loop for c2 = 1 to pcnt
                  c9 = ndata(c2,PS_PASS)
                  if c9 > 0 and tgroup(c9) = c3   /* this typeset group
                    if bit(0,ndata(c2,PS_STEM)) = c5
                      if ndata(c2,PS_PITCH) > c6           /* typeset highest pitch first
                        if c6 > 0 and c15 > EIGHTH         /* but check first to see if
                          if ndata(c2,PS_NTYPE) < QUARTER  /* type is quarter or greater
                            if ndata(c2,PS_PITCH) - c6 < 3
                              goto NOSWITCH
                            end
                          end
                        end
                        c6 = ndata(c2,PS_PITCH)
                        c7 = ndata(c2,PS_PASS)
                        c15 = ndata(c2,PS_NTYPE)
NOSWITCH:
                      else
                        if c15 < QUARTER and ndata(c2,PS_NTYPE) > EIGHTH
                          if c6 - ndata(c2,PS_PITCH) < 3
                            c6 = ndata(c2,PS_PITCH)
                            c7 = ndata(c2,PS_PASS)
                            c15 = ndata(c2,PS_NTYPE)
                          end
                        end
                      end
                    end
                  end
                repeat
                if c7 > 0
                  c8 = 100
                  loop for c2 = 1 to npasses
                    if clashes(c2,c7) = 2         /* unison
                      c8 = c2
                      c2 = 100
                    end
                  repeat
                  perform ps_setchord (c7, c8, c10)
                  goto PS_CC
                end
              repeat
            repeat

      determine if there are clashes left

PS_B:
            loop for c2 = 1 to pcnt - 1
              if ndata(c2,PS_PASS) > 0 and ndata(c2,PS_XPOS) = 0
                             /* chord(PS_PASS) has not been set
                loop for c3 = c2+1 to pcnt
                  if ndata(c3,PS_XPOS) = 0 and ndata(c3,PS_PASS) > 0
                    if ndata(c2,PS_STAFF) = ndata(c3,PS_STAFF)
                      if ndata(c2,PS_PITCH) < 100
                        c4 = ndata(c2,PS_PITCH) - ndata(c3,PS_PITCH)
                        if c4 = 0
                          if bit(0,ndata(c2,PS_STEM)) = bit(0,ndata(c3,PS_STEM))
                            goto PS_CL
                          end
                          if ndata(c2,PS_COLOR) <> ndata(c3,PS_COLOR)
                            goto PS_CL
                          end
#if DOT_DIFFERENCE

      12/24/05  This optional code is now controlled by dot_difference_flag

                          if dot_difference_flag = 1
                            if ndata(c2,PS_DOT) <> ndata(c3,PS_DOT)
                              goto PS_CL
                            end
                          end

#endif
                          if ndata(c2,PS_RANK) * ndata(c3,PS_RANK) <> 1
                            goto PS_CL
                          end
 
            We must now ask the question: are all notes of first chord either
               equal/above all notes of second chord, or equal/below all notes
               of second chord.

                          c10 = 0
                          loop for c9 = 1 to pcnt
                            if ndata(c9,PS_PASS) = ndata(c2,PS_PASS)
                              if ndata(c9,PS_PITCH) <> ndata(c2,PS_PITCH)
                                if ndata(c9,PS_PITCH) > ndata(c2,PS_PITCH)
                                  if c10 = -1
                                    c10 = 1000
                                  else
                                    c10 = 1
                                  end
                                end
                                if ndata(c9,PS_PITCH) < ndata(c2,PS_PITCH)
                                  if c10 = 1
                                    c10 = 1000
                                  else
                                    c10 = -1
                                  end
                                end
                              end
                            end
                          repeat
                          if c10 = 1000
                            goto PS_CL
                          end
                          loop for c9 = 1 to pcnt
                            if ndata(c9,PS_PASS) = ndata(c3,PS_PASS)
                              if ndata(c9,PS_PITCH) <> ndata(c3,PS_PITCH)
                                if ndata(c9,PS_PITCH) > ndata(c3,PS_PITCH)
                                  if c10 = 0
                                    c10 = -1
                                  end
                                  if c10 = 1
                                    c10 = 1000
                                  end
                                end
                                if ndata(c9,PS_PITCH) < ndata(c3,PS_PITCH)
                                  if c10 = 0
                                    c10 = 1
                                  end
                                  if c10 = -1
                                    c10 = 1000
                                  end
                                end
                              end
                            end
                          repeat
                          if c10 = 1000
                            goto PS_CL
                          end
                          goto PS_UNIS     /*  typeset unison
                        end
                        if c4 = 1 or c4 = -1
                          if ndata(c2,PS_PASS) <> ndata(c3,PS_PASS)
                            goto PS_CL
                          end
                        end
                      end
                    end
                  end
                repeat
              end
            repeat

      no clashes found


            putc No clashes


      typeset chords

            loop for c4 = 1 to 2    /* typeset stem down first
              c5 = 2 - c4
PS_C:         c6 = 0
              c7 = 0
              loop for c2 = 1 to pcnt
                if ndata(c2,PS_PASS) > 0 and bit(0,ndata(c2,PS_STEM)) = c5
                  if ndata(c2,PS_PITCH) > c6     /* typeset highest pitch first
                    c6 = ndata(c2,PS_PITCH)
                    c7 = ndata(c2,PS_PASS)
                  end
                end
              repeat
              if c7 > 0
                c8 = 100
                perform ps_setchord (c7, c8, c10)
                goto PS_C
              end
            repeat

      Note: When you have reached this point in the code, you have determined
      the local position of all notes (but not rests) in the simultaneity.  The
      arrays gr(.,.) and gl(,.,) have been computed (if there were notes in
      the simultaneity).  You can now use this information to try to place
      any rests vertically as best you can.  After this, you need to compute
      the NODE_SHIFT parameter (from emptyspace(.,.) and gl(,.,) and then
      the new values for emptyspace(.,.)


            putc typeset music on page
            loop for c2 = 1 to npasses
              putc position of chord ~c2  is ~printpos(c2)
            repeat

      Now store results in set array    (watch out for c9 and c10 in this loop)

            c2 = 0
            c5 = 0
            pitchcnt(1) = 0
            pitchcnt(2) = 0
            loop for c1 = a1 to a2
              ++c2
              c4 = ts(c1,STAFF_NUM) + 1      /* staff number
              thispass = ndata(c2,PS_PASS2)
              if thispass <> c5
                c5 = thispass
                ++pitchcnt(c4)
              end
              if ndata(c2,PS_PITCH) = 100    /* rest
                ntype = ndata(c2,PS_COLOR)
                c6 = ntype << 1 - 1
                c8 = int("1008060402020402030303"{c6,2})
                c7 = int("0505050505030301000101"{c6,2})
                if ps_passcount(c4) = 1
                  c3 = vpar(4)
                  if ts(c1,MULTI_TRACK) >= 4
                    c6 = ts(c1,MULTI_TRACK) >> 2
                    if c6 = 1
                      c3 -= vpar(2)
                    end
                    if c6 = 2
                      c3 += vpar(4)
                    end
                  end
                else
                  if ps_passcount(c4) = 2
                    if pitchcnt(c4) = 1
                      if chr(ts(c1+1,TYPE)) in [NOTE,CUE_NOTE]
                        c3 = ts(c1+1,STAFFLOC)
                      else

        05/10/05 Addition to allow a single rest (expressing parallel rests)
                   to be located at vpar(4), the middle staff line.
                   Note: this work-around may not cover all cases.

                        if ts(c1+1,TYPE) = REST and ts(c1+1,CLAVE) = 200
                          c3 = vpar(4)
                          goto RTYY3
                        else
                          c3 = vpar(2)
                          if ts(c1,NTYPE) < EIGHTH and c3 > 0
                          if (ts(c1,NTYPE) & 0xff) < EIGHTH and c3 > 0    /* new 10/15/07
                            c3 = 0
                          end
                        end

                        c3 = vpar(2)
                        if ts(c1,NTYPE) < EIGHTH and c3 > 0
                          c3 = 0
                        end

                      end
                      c6 = 0 - c3 / vpar(1) + 23
                      c11 = c3 + vpar20 * 2 + 1 / vpar(2) - 20
                      c6 = 23 - c11

                      c13 = c6
                      loop while gr(c4,c6) <> -200
                        c3 -= vpar(1)
                        c3 -= vpar(1)
                        c11 = c3 * 2 / vpar(2)
                        c3 -= rem                 /* tricky code

                        ++c6
                      repeat
                      c6 -= c7                          /* c7 is lower part of rest
                      loop while gr(c4,c6) <> -200
                        c3 -= vpar(1)
                        c3 -= vpar(1)
                        c11 = c3 * 2 / vpar(2)
                        c3 -= rem                 /* tricky code

                        ++c6
                      repeat
                      if c6 > c13 + 8
                        c3 += vpar(2)
                      end
                      if c3 > vpar(2)
                        c3 = vpar(2)
                      end
                      c6 = c3 / notesize
                      if rem <> 0
                        c3 -= vpar(1)     /* OK 4-21-95
                      end
                    else
                      if chr(ts(c1-1,TYPE)) in [REST,CUE_REST]
                        if ts(c1-1,CLAVE) < 200 or scr_flag = 0
                          c3 = vpar(8)
                        else
                          c3 = vpar(4)
                          goto RTYY3
                        end
                      else
                        c3 = ts(c1-1,STAFFLOC) + vpar(2)
                      end
                      c6 = 0 - c3 / vpar(1) + 23
                      c11 = c3 + vpar20 * 2 + 1 / vpar(2) - 20
                      c6 = 23 - c11

                      c13 = c6
                      loop while gr(c4,c6) <> -200
                        c3 += vpar(1)
                        c11 = c3 * 2 / vpar(2)
                        if rem <> 0               /* tricky code
                          ++c3
                        end
                        c3 += vpar(1)

                        --c6
                      repeat
                      c6 += c8                          /* c8 is "clearance" at top of rest
                      loop while gr(c4,c6) <> -200
                        c3 += vpar(1)
                        c11 = c3 * 2 / vpar(2)
                        if rem <> 0               /* tricky code
                          ++c3
                        end
                        c3 += vpar(1)

                        --c6
                      repeat
                      if c6 < c13 - 8
                        c3 -= vpar(2)
                      end
                      if c3 < vpar(8)
                        c3 = vpar(8)
                      end
                      c6 = c3 / notesize
                      if rem <> 0
                        c3 += vpar(1)
                        c3 = c6 + 1 * notesize

                      end
                    end
                  else
                    if pitchcnt(c4) = 1
                      if chr(ts(c1+1,TYPE)) in [NOTE,CUE_NOTE]
                        c3 = ts(c1+1,STAFFLOC)
                      else
                        c3 = vpar(2)
                      end
                      if ts(c1,NTYPE) < EIGHTH and c3 > 0
                      if (ts(c1,NTYPE) & 0xff) < EIGHTH and c3 > 0     /* new 10/15/07
                        c3 = 0
                      end
                      c6 = 0 - c3 / vpar(1) + 23
                      c11 = c3 + vpar20 * 2 + 1 / vpar(2) - 20
                      c6 = 23 - c11

                      c13 = c6
                      loop while gr(c4,c6) <> -200
                        c3 -= vpar(1)
                        c3 -= vpar(1)
                        c11 = c3 * 2 / vpar(2)
                        c3 -= rem                 /* tricky code

                        ++c6
                      repeat
                      c6 -= c7                          /* c7 is lower part of rest
                      loop while gr(c4,c6) <> -200
                        c3 -= vpar(1)
                        c3 -= vpar(1)
                        c11 = c3 * 2 / vpar(2)
                        c3 -= rem                 /* tricky code

                        ++c6
                      repeat
                      if c6 > c13 + 8
                        c3 += vpar(2)
                      end
                      if c3 > vpar(2)
                        c3 = vpar(2)
                      end
                      c6 = c3 / notesize
                      if rem <> 0
                        c3 -= vpar(1)      /* OK 4-21-95
                      end
                    else
                      if pitchcnt(c4) = ps_passcount(c4)
                        if chr(ts(c1-1,TYPE)) in [REST,CUE_REST]
                          if ts(c1-1,CLAVE) < 200 or scr_flag = 0
                            c3 = vpar(10)
                          else
                            c3 = vpar(4)
                          end
                        else
                          c3 = ts(c1-1,STAFFLOC) + vpar(2)
                        end
                        c6 = 0 - c3 / vpar(1) + 23
                        c11 = c3 + vpar20 * 2 + 1 / vpar(2) - 20
                        c6 = 23 - c11

                        c13 = c6
                        loop while gr(c4,c6) <> -200
                          c3 += vpar(1)
                          c11 = c3 * 2 / vpar(2)
                          if rem <> 0               /* tricky code
                            ++c3
                          end
                          c3 += vpar(1)

                          --c6
                        repeat
                        c6 += c8                          /* c8 is "clearance" at top of rest
                        loop while gr(c4,c6) <> -200
                          c3 += vpar(1)
                          c11 = c3 * 2 / vpar(2)
                          if rem <> 0               /* tricky code
                            ++c3
                          end
                          c3 += vpar(1)

                          --c6
                        repeat
                        if c6 < c13 - 8
                          c3 -= vpar(2)
                        end
                        if c3 < vpar(8)
                          c3 = vpar(8)
                        end
                        c6 = c3 / notesize
                        if rem <> 0
                          c3 += vpar(1)
                          c3 = c6 + 1 * notesize

                        end
                      else

                Look for empty space in middle of staff

                        loop for c3 = 45 to 1 step -1
                        repeat while gr(c4,c3) = -200
                        if c3 <= 21                      /* suppose there's nothing up there
                          c3 += 3
                          if c3 < 19
                            c3 = 19
                          end
                          goto RTYY2
                        end
                        loop while c3 > 0
                          --c3
                        repeat while gr(c4,c3) <> -200
RTYY:
                        loop for c6 = 1 to 8
                          --c3
                        repeat while c3 > 0 and gr(c4,c3) = -200
                        if c6 = 8 or c3 <= 0
                          c3 += 3
                        else
                          goto RTYY
                        end
RTYY2:
                        c3 = 23 - c3 * vpar(1)
                        c3 = 43 - c3 / 2 * vpar(2)
                        c3 += rem * vpar(1)
                        c3 -= vpar20
                      end
                    end
                  end
                end
RTYY3:
                if ts(c1,CLAVE) < 200 or scr_flag = 0
                  if ts(c1,STAFFLOC) = 1
                    c3 = vpar(4)
                  end
                  ts(c1,STAFFLOC) = c3
                  perform rest_occupy_space (c3,c4)   /* ntype is read directly
                  ts(c1,OBY) = ts(c1,STAFFLOC)
                end
              else
                c3 = ndata(c2,PS_COLOR)
                if c3 < 3
                  c4 = hpar(82)
                else
                  if c3 = 3
                    c4 = hpar(83)
                  else
                    c4 = hpar(84)
                  end
                end
                if ndata(c2,PS_NSIZE) = CUESIZE
                  c4 = c4 * 8 / 10
                end

                c4 -= 1

      Note: LOCAL_XOFF will now be set for this notehead, and will not be changed.
            The value is negative, zero, or positive by the approximate thickness
            of a notehead.  This information can be used in the final computation
            of P10 for this notehead.

                ts(c1,LOCAL_XOFF)  = c4 * ndata(c2,PS_XPOS)     /* uniquely set here


    NOTE: Do not call procedure get_topbottom before this point in the program



      Note: We are about to set GLOBAL_XOFF for all noteheads in a chord
            to the value in printpos(thispass).  The spacing of simultaneous
            chords in this program is hopelessly complicated.  Therefore
            we cannot know directly whether a notehead has been shifted
            exactly one thickness to the right or left, or whether the
            shift has been built up in several parts.  All we know is that
            the shift adds up to GLOBAL_XOFF.  In order to set the NOTE_DISP
            parameter properly, we will need to compare GLOBAL_XOFF with autoscr's
            normal shift distance = (width of black note - 2).  If GLOBAL_XOFF
            is within 2 dots either side of +/- (hpar(82) - 2), then we will
            infer that the shift was an integral notehead thickness; otherwise
            we must record the shift measured in dots.  A shift of an
            integral notehead thickness will be recorded as -100 or +100.

                if chr(ts(c1,TYPE)) in [NOTE,CUE_NOTE,GR_NOTE]
                  c9 = c1
                  ts(c1,GLOBAL_XOFF) = printpos(thispass)

                               All New code 05/02/03

        At this point, we need to see if the note object position has been modified
        "absolutely" by a print suggestion.  If this is the case, we need to make the
        adjustment here, AND, elimate the suggestion from the tsr string.

                  c4 = ts(c1,TSR_POINT)
                  c3 = ors(tsr(c4){2})
                  if bit(0,c3) = 1
                    px = ors(tsr(c4){3})
                    if px > 0
                      px = px - 128 * notesize / 10

      11/24/07  We need to take action in both the relative and
      absolute cases of x-shift.  Apparently, there is a difference,
      at least here.  Relative shift ("x") is added to whatever is
      already in the GLOBAL_XOFF; whereas absolute shift ("X") replaces
      any value in GLOBAL_XOFF.  This holds for note placement, but
      I am unclear whether it is true for musical signs, dynamics, etc.

                      pxx = c3 & 0x02 >> 1
                      if pxx = 1                    /* true when "X" is used
                        ts(c1,GLOBAL_XOFF) = px
                        tsr(c4){3} = chr(0)         /* here is where suggestion is zeroed out
                      else
                        ts(c1,GLOBAL_XOFF) += px
                        tsr(c4){3} = chr(0)         /* here is where suggestion is zeroed out
                      end

                      if pxx = 1                    /* true when "X" is used
                        ts(c1,GLOBAL_XOFF) = px
                        tsr(c4){3} = chr(0)         /* here is where suggestion is zeroed out
                      end

                    end
                  end
                  printpos(thispass) = ts(c1,GLOBAL_XOFF)

        End of new code 05/02/03

#if AUTOSCR
                  c3 = printpos(thispass)
                  if c3 <> 0
                    if ts(c1,TYPE) = NOTE
                      c4 = hpar(82) - 2              /* autoset doesn't shift full width
                    else
                      c4 = hpar(82) * 8 / 10 - 2
                    end
                    if abs(c3) > c4 - 3 and abs(c3) < c4 + 3
                      if c3 > 0
                        ts(c1,NOTE_DISP) = 100
                      else
                        ts(c1,NOTE_DISP) = -100
                      end
                    else
                      ts(c1,NOTE_DISP) = scr_qwidth * INT10000 + c3
                    end
                  else
                    ts(c1,NOTE_DISP) = 0
                  end
#endif
                  c10 = c1 + 1
                  loop while ts(c10,TYPE) = ts(c1,TYPE) + 1
                    ++c10
                  repeat
                  --c10
                else
                  ts(c1,GLOBAL_XOFF) = c9 * INT10000 + c10    /* temporary storage of indexes
                  ts(c1,NOTE_DISP) = ts(c9,NOTE_DISP)
                end
              end
            repeat


 ***************************************************************
    Debug Information

            if bit(2,pmode) = 1 and g >= debug_point

     Condition changed 01/01/06

            g = measnum - 1
            if (bit(2,pmode) = 1 or debug_flag = 1) and g >= debug_point
              putc   Set Array at Point No. 3:  measure ~g
              putc Look?
              getc jtype
              if jtype = "y"
                perform display_ts
              end
            end

    End debug information
 ***************************************************************


            goto PS_END


      Clashes

PS_CL:
            putc clash  c2 = ~c2   c3 = ~c3
            c4 = ndata(c2,PS_PASS)
            c5 = ndata(c3,PS_PASS)
            if ndata(c2,PS_DOT) > 0 and ndata(c3,PS_DOT) = 0
              c7 = c5
              goto PS_CLT
            end
            if ndata(c2,PS_DOT) = 0 and ndata(c3,PS_DOT) > 0
              c7 = c4
              goto PS_CLT
            end
            if bit(0,ndata(c2,PS_STEM)) = UP and bit(0,ndata(c3,PS_STEM)) = DOWN
              c7 = c4
              goto PS_CLT
            end
            if bit(0,ndata(c2,PS_STEM)) = DOWN and bit(0,ndata(c3,PS_STEM)) = UP
              c7 = c5
              goto PS_CLT
            end
            if ndata(c2,PS_PITCH) >= ndata(c3,PS_PITCH)
              c7 = c4
            else
              c7 = c5
            end
PS_CLT:
            putc clash between pitch chords ~c4  and ~c5
            c8 = 100
            perform ps_setchord (c7, c8, c10)
            goto PS_B
*
PS_UNIS:
            putc unison  c2 = ~c2   c3 = ~c3
            c7 = ndata(c2,PS_PASS)
            c8 = ndata(c3,PS_PASS)
            perform ps_setchord (c7, c8, c10)
            goto PS_B

PS_END:


      At this point you have accomplished tasks (1), (2), and (3)
      for the case of multiple note heads on a division.  You now
      need to do the following (for all ts(.,.) elements from a1
      to a2).

        (4) Compute the x and y offsets for any dot(s) which might
            follow each note head.

        (5) Compute the x offset (as measured to the left) of any
              accidental(s) which might precede each note head.



      (4) X and Y offsets for dots

        (a) determine number and spacing of note heads on each stave
              to determine method of placement of dots.  Use column
              method if note heads (with dots) occur on space and line
              on the same staff.  Otherwise use conventional placement.
              (This code assumes MAX_STAFF <= 3)

              First find all staves where all offsets (global and local)
              are zero.  In these cases, we can use the absolute method.

            tgroup(1) = 4
            tgroup(2) = 4
            tgroup(3) = 4
            loop for c1 = a1 to a2
              c8 = ts(c1,STAFF_NUM) + 1        /* staff number
              if chr(ts(c1,TYPE)) in [NOTE,CUE_NOTE,GR_NOTE]
                if ts(c1,GLOBAL_XOFF) > 0
                  tgroup(c8) = 0
                end
              end
              if ts(c1,LOCAL_XOFF) > 0
                tgroup(c8) = 0
              end
            repeat

            loop for c1 = a1 to a2
              if ts(c1,DOT) > 0
                c8 = ts(c1,STAFF_NUM) + 1      /* staff number
                if tgroup(c8) <> 4
                  c9 = ts(c1,STAFFLOC) / vpar(1)
                  c9 = ts(c1,STAFFLOC) + vpar20 * 2 + 1 / vpar(2) - 20

                  c9 = bit(0,c9) + 1
                  if tgroup(c8) = 0
                    tgroup(c8) = c9
                  else
                    if tgroup(c8) <> c9
                      tgroup(c8) = 3           /* use column method
                    end
                  end
                end
              end
            repeat

        (b) for those staves using the column method, determine the
              x offset of the column.

            c5 = 0
            loop for c8 = 1 to 3
              if tgroup(c8) = 3
                tgroup(c8) = 1
                c5 = 1
              else
                tgroup(c8) = 0
              end
            repeat
            if c5 = 1
              loop for c1 = a1 to a2
                if ts(c1,GLOBAL_XOFF) < INT10000
                  c9 = ts(c1,GLOBAL_XOFF)                    /* global offset
                end
                if ts(c1,DOT) > 0
                  c8 = ts(c1,STAFF_NUM) + 1                  /* staff number
                  if tgroup(c8) > 0
                    c7 = c9 + ts(c1,LOCAL_XOFF)              /* note head position
                    c10 = ts(c1,TYPE) / 3
                    if rem = 0
                      if ts(c1,NTYPE) > QUARTER
                        c3 = hpar(30)
                      else
                        c3 = hpar(31)
                      end
                    else
                      if ts(c1,NTYPE) > HALF
                        c3 = hpar(32)
                      else
                        c3 = hpar(33)
                      end
                    end
                    if rem = 1 and bit(1,ts(c1,STEM_FLAGS)) = UP
                      if ts(c1,BEAM_FLAG) = NO_BEAM and ts(c1,NTYPE) < QUARTER
                        c3 += hpar(27)
                      end
                    end
                    if ts(c1,TYPE) > REST
                      c3 = c3 * 8 / 10
                    end
                    c7 += c3             /* dot position for this note head
                    if tgroup(c8) < c7
                      tgroup(c8) = c7
                    end
                  end
                end
              repeat
 
        (c) place dots for all staves which use the column method
              (relative x placement; absolute y placement)

            Starting with the left-most objects in the "musical node"
            and moving to the right, set dot positions according to
            the following algorithm (keeping track of all previous
            dots for this stave):

               Start with the note head furtherest from note-end of stem
               If note on line,
                 if space above is free, put dot there
                 else put dot in first free space below
               else
                 if space is free, put dot there
                 else put dot in first free space in reverse direction
               end

              loop for c13 = 1 to 3       /* loop though staves
                if tgroup(c13) > 0
                  c5 = 0
                  c10 = 0                 /* count up for stems up
                  c11 = 1000              /* count down for stems down

     Special case: two notes on stave and multi-tracks on this stave

                  if a2 = a1 + 1
                    if ts(a1,MULTI_TRACK) >= 4
                      if abs(ts(a1,STAFFLOC) - ts(a2,STAFFLOC)) > notesize
                        if bit(1,ts(a1,STEM_FLAGS)) <> bit(1,ts(a2,STEM_FLAGS))
                          loop for c1 = a1 to a2
                            c8 = ts(c1,GLOBAL_XOFF)
                            if c8 >= INT10000
                              c8 /= INT10000
                              c8 = ts(c8,GLOBAL_XOFF)
                            end
#if AUTOSCR

                      Start by setting the SCORE P9 parameter (AUG_DOTS)

                            c16 = ts(c1,STAFFLOC) / notesize
                            c16 = rem                            /* set 16 to rem

                            c9 = tgroup(c13)
                            if ts(c1,TYPE) > XNOTE
                              c9 = c9 * 10 + 6 / 8
                            end
                            if ts(c1,NTYPE) > HALF
                            if (ts(c1,NTYPE) & 0xff) > HALF      /* new 10/15/07
                              c9 -= hpar(32)
                            else
                              c9 -= hpar(33)
                            end

                            if c9 < 3
                              c9 = 0
                            end
                            if ts(c1,TYPE) > XNOTE
                              c9 = c9 * 8 / 10
                            end

                            c9 = c9 * 30 / scr_qwidth               /* 100ths part of P9
                            if c9 > 99
                              c9 = 99
                            end
                            c10 = ts(c1,DOT) & 0x0f
                            c10 = int("1.2...3.......4"{c10})     /* convert to SCORE code
                            c10 *= 10
                            if c16 = 0 and bit(1,ts(c1,STEM_FLAGS)) = DOWN
                              c10 += 100
                            end
                            c10 = c10 << 8 + c9
                            ts(c1,AUG_DOTS) = c10
#endif
                            c10 = ts(c1,STAFFLOC)
                            c9 = c10 / notesize
                            if rem = 0                 /* note on line
                              if bit(1,ts(c1,STEM_FLAGS)) = UP
                                c10 -= vpar(12)
                              else
                                c10 += vpar(12)
                              end
                            end
                            c10 -= ts(c1,OBY)          /* convert to relative y offset
                            c9 = tgroup(c13) - c8      /* relative x offset from obx
                            c9 *= INT10000
                            c9 += c10
                            c9 <<= 4                   /* code modified 12-24-96
                            ts(c1,DOT) |= c9
                          repeat
                          goto X_DOT
                        end
                      end
                    end
                  end                                        /* global offset

                  loop for c1 = a1 to a2
                    if ts(c1,GLOBAL_XOFF) < INT10000
                      c9 = ts(c1,GLOBAL_XOFF)                /* global offset
                    end
                    c8 = ts(c1,STAFF_NUM) + 1         /* staff number
                    if ts(c1,DOT) > 0 and c8 = c13    /* dot on this staff
                      ++c5
                      c12 = bit(1,ts(c1,STEM_FLAGS))
                      if c12 = UP       /* stem up
                        ndata(c5,1) = c10
                        ++c10
                      else
                        ndata(c5,1) = c11
                        --c11
                      end
                      ndata(c5,1) += c9 * 10000        /* tricky code (for ordering)
                      ndata(c5,2) = c1
                      ndata(c5,3) = c12                /* stem direction
                      ndata(c5,4) = c9                 /* global x offset
                      ndata(c5,5) = 100
                    end
                  repeat

            Sort the ndata array by ndata(.,1) smallest on top
            first by global offset, then by stem (up first), then by order
            on stem (up in order, down reverse order)

                  loop for c8 = 1 to c5
                    c6 = 10000000
                    loop for c4 = 1 to c5
                      if ndata(c4,5) = 100 and ndata(c4,1) < c6
                        c6 = ndata(c4,1)
                        c7 = c4
                      end
                    repeat
                    ndata(c7,6) = c8
                    ndata(c7,5) = 0
                  repeat

            Typeset dots on this staff

                  loop for c8 = 1 to 50
                    mf(c8) = 0
                  repeat
                  loop for c8 = 1 to c5
                    c7 = ndata(c8,6)                /* typeset this note head
                    c1 = ndata(c7,2)                /* c1 is the index
                    c9 = tgroup(c13) - ndata(c7,4)  /* relative x offset from obx
                    c4 = 0 - ts(c1,STAFFLOC) / vpar(1) + 23
                    c16 = ts(c1,STAFFLOC) + vpar20 * 2 + 1 / vpar(2) - 20
                    c4 = 23 - c16                            /* 23 = top line of staff


               If note on line,
                 if space above is free, put dot there
                 else put dot in first free space below
               else
                 if space is free, put dot there
                 else put dot in first free space in reverse direction
               end

                    if bit(0,c4) = 1                /* if note on line
                      if mf(c4+1) = 0
                        mf(c4+1) = 1
                        c10 = c4 + 1                /* absolute y offset (23 = top line)
                      else
                        c10 = 0
                        --c4
                        loop
                          if mf(c4) = 0
                            mf(c4) = 1
                            c10 = c4
                          else
                            c4 -= 2
                            if c4 = 0
                              putc Program error setting dots
                              stop
                            end
                          end
                        repeat while c10 = 0
                      end
                    else                            /* else, note on space
                      if mf(c4) = 0
                        mf(c4) = 1
                        c10 = c4
                      else
                        if ndata(c7,3) = UP         /* if stem up, look up
                          c10 = 0
                          c4 += 2
                          loop
                            if mf(c4) = 0
                              mf(c4) = 1
                              c10 = c4
                            else
                              c4 += 2
                              if c4 = 50
                                putc Program error setting dots
                                stop
                              end
                            end
                          repeat while c10 = 0
                        else                        /* else, stem is down; look down
                          c10 = 0
                          c4 -= 2
                          loop
                            if mf(c4) = 0
                              mf(c4) = 1
                              c10 = c4
                            else
                              c4 -= 2
                              if c4 = 0
                                putc Program error setting dots
                                stop
                              end
                            end
                          repeat while c10 = 0
                        end
                      end
                    end

              c10 is the absolute y position (23 = top line) for the dot(s)

                    c10 = 23 - c10 * vpar(1)   /* convert to absolute staff position
                    c10 = 43 - c10 / 2 * vpar(2)
                    c10 += rem * vpar(1)
                    c10 -= vpar20
#if AUTOSCR

            This is all getting pretty hairy, but we need to try to convert
            the current shift data to data that SCORE can use.  The problem
            with SCORE is that it does not allow a dot to be shifted down
            by more than one scale step.  This creates problems even for
            SCORE data entry, but it creates nightmares for conversion, unless
            we simply set every dot using CODE-9 items.  I will attempt a
            compromise.  If the y-position is "settable" with a SCORE P9
            parameter, I will do it; otherwise we need to use a CODE-9 item.
            I shutter to think of what the output of this will look like.

            Use c7,c16,c4,c12

                    c16 = ts(c1,STAFFLOC)
                    c4 = c16 / notesize
                    c4 = rem
                    if (c4 = 0 and abs(c16 - c10) < vpar(2)) or (c4 <> 0 and c16 = c10)

                               /* can set with SCORE

                      c7 = c9
                      if ts(c1,TYPE) > XNOTE
                        c7 = c7 * 10 + 6 / 8
                      end
                      if ts(c1,NTYPE) > HALF
                      if (ts(c1,NTYPE) & 0xff) > HALF      /* new 10/15/07
                        c7 -= hpar(32)
                      else
                        c7 -= hpar(33)
                      end

                      if c7 < 3
                        c7 = 0
                      end
                      if ts(c1,TYPE) > XNOTE
                        c7 = c7 * 8 / 10
                      end

                      c12 = ts(c1,GLOBAL_XOFF)
                      if c12 >= INT10000
                        c12 /= INT10000                      /* index to top note
                        c12 = ts(c12,GLOBAL_XOFF)
                      end

                      c7 = c7 * 30 / scr_qwidth             /* 100ths part of P9
                      if c7 > 99
                        c7 = 99
                      end
                      c12 = ts(c1,DOT) & 0x0f
                      c12 = int("1.2...3.......4"{c12})     /* convert to SCORE code
                      c12 *= 10
                      if c4 = 0 and c10 > c16               /* dot below notehead
                        c12 += 100
                      end
                      c12 = c12 << 8 + c7
                      ts(c1,AUG_DOTS) = c12
                    else
                      ts(c1,AUG_DOTS) = 0x01000000          /* goto CODE-9
                      ts(c1,AUG_DOTS) += (c9 * INT10000)
                      ts(c1,AUG_DOTS) += c10
                    end
#endif

            Store relative values of x and y for this note head
              c9 is the relative x shift to the dot(s) from obx
              x * INT10000 + y, shift it over 4 and OR it DOT   (modified 12-24-96)

                    c9 *= INT10000
                    c10 -= ts(c1,OBY)          /* convert to relative y offset
                    c9 += c10
                    c9 <<= 4                   /* code modified 12-24-96
                    ts(c1,DOT) |= c9
                  repeat
X_DOT:

                end
              repeat
            end
 
        (d) place dots for all remaining note heads (absolute placement first)

            old_c2 = 10000                    /* added 11/26/06
            loop for c1 = a1 to a2
              if ts(c1,DOT) > 0 and ts(c1,DOT) < INT9000      /* dot not yet placed
                ntype = ts(c1,NTYPE)
                ntype = ts(c1,NTYPE) & 0xff                   /* new 10/15/07
                c10 = ts(c1,TYPE) / 3
                if rem = 0                    /* rests
                  if ntype > QUARTER
                    c3 = hpar(30)
                  else
                    c3 = hpar(31)
                  end
                else
                  if ntype > HALF
                    c3 = hpar(32)
                  else
                    c3 = hpar(33)
                  end
                end
                c6 = ts(c1,STAFFLOC) / vpar(1)
                c6 = ts(c1,STAFFLOC) + vpar20 * 2 + 1 / vpar(2) - 20
                c5 = ts(c1,STAFFLOC) / notesize
                c5 = rem                           /* c5 = 0 means note on line

                if bit(1,ts(c1,STEM_FLAGS)) = UP
                  if ts(c1,BEAM_FLAG) = NO_BEAM and ts(c1,NTYPE) < QUARTER
                    c10 = ts(c1,TYPE) / 3
                    if rem = 1
                      c3 += hpar(27)
                      if c5 <> 0
                        c3 -= hpar(34)
                      end
                    end
                  end
                end
*    if dot is on staff line, c5 = 0
                if c5 = 0
                  c2 = 0 - vpar(12)
           /* lower dot if more than one track and stem is down
                  if bit(3,ts(c1,MULTI_TRACK)) = 1
                    if bit(1,ts(c1,STEM_FLAGS)) = DOWN
                      c2 = vpar(12)
                    end
                  end
                  c3 -= hpar(34)
                else
                  c2 = 0
                end
                if ts(c1,TYPE) <= REST
                  c5 = bit(16,ts(c1,SUBFLAG_1))
                else
                  c5 = CUESIZE
                end
                if c5 = 1
                  c3 = c3 * 8 / 10
                end
                c2 += ts(c1,STAFFLOC)
#if AUTOSCR
                if ts(c1,TYPE) <> REST and ts(c1,TYPE) <> CUE_REST

          use c7,c16,c4,c12,c5

                  c16 = ts(c1,STAFFLOC)
                  c4 = c16 / notesize
                  c4 = rem
                  if (c4 = 0 and abs(c16 - c2) < vpar(2)) or (c4 <> 0 and c16 = c2)

                             /* can set with SCORE

                    c7 = c3
                    if ts(c1,TYPE) > XNOTE
                      c7 = c7 * 10 + 6 / 8
                    end
                    if ts(c1,NTYPE) > HALF
                    if (ts(c1,NTYPE) & 0xff) > HALF            /* new 10/15/07
                      c7 -= hpar(32)
                    else
                      c7 -= hpar(33)
                    end
                    if c4 = 0
                      c7 += hpar(34)
                    end

                    if c7 < 3
                      c7 = 0
                    end
                    if ts(c1,TYPE) > XNOTE
                      c7 = c7 * 8 / 10
                    end
                    c12 = ts(c1,GLOBAL_XOFF)
                    if c12 >= INT10000
                      c12 /= INT10000
                      c12 = ts(c12,GLOBAL_XOFF)
                    end

                    c7 = c7 * 30 / scr_qwidth             /* 100ths part of P9
                    if c7 > 99
                      c7 = 99
                    end
                    c12 = ts(c1,DOT) & 0x0f
                    c12 = int("1.2...3.......4"{c12})     /* convert to SCORE code
                    c12 *= 10
                    if c4 = 0 and c2 > c16                 /* dot below notehead
                      c12 += 100
                    end
                    c12 = c12 << 8 + c7
                    ts(c1,AUG_DOTS) = c12
                  else
                    c12 = ts(c1,DOT) & 0x0f
                    c12 = int("1.2...3.......4"{c12})     /* convert to SCORE code
                    c12 <<= 24
                    ts(c1,AUG_DOTS) = c12                 /* goto CODE-9
                    ts(c1,AUG_DOTS) += (c3 * INT10000)
                    ts(c1,AUG_DOTS) += c2
                  end
                end

#endif
                c2 -= ts(c1,OBY)

     This code added 11/26/06 (as a cludge) to fix a minor bug in the
       placement extension dots when one is "on top of" another.

                if ts(c1,TYPE) = XNOTE or ts(c1,TYPE) = XCUE_NOTE or ts(c1,TYPE) = XGR_NOTE
                  if abs(old_c2 - c2) < vpar(1)
                    c2 += vpar(2)
                  end
                end
                old_c2 = c2

                  End of 11/26/06 addition

             /* c3 = x offset to the dot(s) from obx
             /* c2 = y offset to the dot(s) from oby
             /* x * INT10000 + y, shift it over 4 and OR it with DOT  (modified 12-24-96)
                c3 *= INT10000
                c3 += c2
                c3 <<= 4                                   /* code modified 12-24-96
                ts(c1,DOT) |= c3
              end
            repeat

        Adjust the gr(.,.) array to accommodate space for dots

            c17 = 0                                        /* used below
            loop for c1 = a1 to a2
              if ts(c1,GLOBAL_XOFF) < INT10000
                c9 = ts(c1,GLOBAL_XOFF)                    /* global offset
              end
              c8 = ts(c1,STAFF_NUM) + 1                    /* staff number



      Special code added to deal with the discrepency in how single vs. multiple
      tracks handle the minimal spacing for dotted rests.   04/19/08
      This section computes the value of the right hand border for the dot, c7
      It also sets the exception variable c17 = 1

              c7 = 10000                                 /* "normal" condition
              if scr_flag = 1
                if c1 < a2 and ts(c1,TYPE) = REST
                  if ts(c1+1,TYPE) = REST and ts(c1+1,CLAVE) = 200
                    if ts(c1,DOT) > 0
                      c7 = 1
                    end
                    c17 = 1                              /* used below
                  end
                end
              end

              c3 = ts(c1,DOT)
              if c3 > 0

                if c7 = 1

                  ntype = ts(c1,NTYPE) & 0xff

                  c4 = 0
                  if ntype <= SIXTEENTH
                    c4 = EIGHTH - ntype
                  end
                  if ntype > QUARTER
                    c7 = hpar(30)
                  else
                    c7 = c4 * hpar(54) + hpar(31)
                  end

                  c7 += hpar(80)

                  if ntype > WHOLE
                    c4 = hpar(87) * 4 / 3
                  else
                    if ntype > QUARTER
                      c4 = hpar(87)
                    else
                      if ntype > EIGHTH
                        c4 = hpar(88)
                      else
                        c4 = EIGHTH - ntype * hpar(54) + hpar(88)
                      end
                    end
                  end

                  c7 += c4

                  if ts(c1,DOT) & 0x0e > 0
                    if ts(c1,DOT) & 0x02 > 0
                      c7 += hpar(91)                    /* extra shift to second dot
                    end
                    if ts(c1,DOT) & 0x04 > 0
                      c7 += hpar(91)                    /* extra shift to third dot
                    end
                    if ts(c1,DOT) & 0x08 > 0
                      c7 += hpar(91)                    /* extra shift to fourth dot
                    end
                  end

                  dputc gr(.) = ~c7

                end



                c4 = c3 & 0x0f               /* dot flag    (modified 12-24-96)
                c3 >>= 4                                    /* code modified 12-24-96
                c5 = c3 / INT10000           /* x offset
                c6 = rem                     /* y offset
                if c6 > INT10000 >> 1
                  c6 -= INT10000
                  ++c5
                end
                c6 = c6 + vpar(8) - 1 / vpar(1) - 7
                c6 = c6 + vpar(8) * 2 - 1 / vpar(2) - 7

                c6 = 0 - ts(c1,STAFFLOC) / vpar(1) + 23 - c6
                c16 = ts(c1,STAFFLOC) + vpar20 * 2 + 1 / vpar(2) - 20
                c6 = 23 - c16 - c6

                c5 += c9 + ts(c1,LOCAL_XOFF)               /* final offset for dot
                c5 += hpar(80)
                if c4 > 1                                  /* code modified 12-24-96
                  c5 += hpar(91)              /* second dot
                  if c4 > 4
                    c5 += hpar(91)            /* third dot
                  end
                  if c4 > 8
                    c5 += hpar(91)            /* fourth dot
                  end
                end
                if c6 < 46 and c6 > 0



      More code added to deal with the discrepency in how single vs. multiple
      tracks handle the minimal spacing for dotted rests.   04/19/08
      This section sets the value of the right hand object "border" gr(.,.)


                  gr(c8,c6) = c5

                  if c7 = 10000                 /* "normal" condition
                    gr(c8,c6) = c5
                  else
                    gr(c8,c6) = c7
                    if c6 < 44
                      gr(c8,c6+1) = c7
                      gr(c8,c6+2) = c7
                    end
                  end



                end
              end
            repeat


      (5) Compute the x offset (as measured to the left) of any
              accidental(s) which might precede each note head.

        (a) Check the left-hand border from the typesetting operation.
            If there are any accidentals that could be set on right-
            shifted note heads, set these first, starting from the
            top down.  This defines column 1 of the accidentals.

            Otherwise, column one is the first free location to the
            left of the left-most note head.

        (b) For all remaining accidentals to set, start at the top
            of the group.  Make successive passes until all accidentals
            are set.

             1. moving down, put in as many accidentals as possible
                where the distance between eligible notes (delta) >=
                vpar(6), with the caviat that you do not put an
                accidental on the lower half of a second before the
                upper half of a second (as you move down).

             2. move to the left by the largest thickness of accidentals
                just placed.  Decide on the direction to move for the
                next pass and goto (a).  The new direction will be
                down (again) if the previous pass hit the lowest remaining
                accidental; otherwise, the new direction will be up.

        (Maximum staves for this code is 2, because this is the size of gl(.,.))

            tgroup(1) = 0
            tgroup(2) = 0
            tgroup(3) = 0
            c5 = 0

            loop for c1 = a1 to a2
              if ts(c1,AX) > 0
                c8 = ts(c1,STAFF_NUM) + 1        /* staff number
                ++tgroup(c8)
                ndata(tgroup(c8),c8) = c1
                c5 = 1
              end
            repeat
            if c5 = 1                     /* Don't change this variable (c5)
                                          /* until task (1) is complete
              loop for c13 = 1 to 2       /* loop though staves
                if tgroup(c13) > 0
                  if a1 = a2              /* simple case (one note group)
                    c1 = ndata(1,c13)     /* index
                    c3 = ts(c1,AX) & 0x0f
                    c2 = 0 - ts(c1,STAFFLOC) / vpar(1) + 23
                    c16 = ts(c1,STAFFLOC) + vpar20 * 2 + 1 / vpar(2) - 20
                    c2 = 23 - c16

                    if ts(c1,TYPE) > REST
                      c4 = CUESIZE
                    else
                      c4 = bit(16,ts(c1,SUBFLAG_1))
                    end
                    perform place_accidental (c13,c2,c3,c4) /* returns c4 = absolute x
                    ts(c1,AX_DISP) = c3  /* capture this parameter, from place_accidental

              /* shift offset left 8 and OR with AX
                    c4 = 0 - c4
                    c4 <<= 8             /* 02/25/97 shift changed from 4 to 8
                    ts(c1,AX) |= c4
                  else

         (1) We must re-order elements so that they are in descending
               order on the staff.  Use bubble sort.

                    loop for c7 = 1 to tgroup(c13) - 1
                      loop for c8 = c7+1 to tgroup(c13)
                        c1 = ndata(c7,c13)
                        c2 = ndata(c8,c13)
                        if ts(c1,STAFFLOC) > ts(c2,STAFFLOC)
                          ndata(c7,c13) = c2
                          ndata(c8,c13) = c1
                        end
                      repeat
                    repeat
 
         (2) Try first to set accidentals on "right shifted chords"

                    loop for c8 = 1 to tgroup(c13)
                      c1 = ndata(c8,c13)
                      if c8 > 1
                        c2 = ndata(c8-1,c13)
                        if c2 < DUMMY_VALUE
                          if ts(c1,STAFFLOC) - ts(c2,STAFFLOC) = vpar(1)  /* second
                          c16 = ts(c1,STAFFLOC) - ts(c2,STAFFLOC)
                          if c16 = vpar(1) or c16 = vpar(1) + 1           /* second
                            if ts(c1,LOCAL_XOFF) < ts(c2,LOCAL_XOFF)
                              /* don't set accidental in this situation
                              goto QQQ1
                            end
                          end
                        end
                      end
                      c2 = 0 - ts(c1,STAFFLOC) / vpar(1) + 23
                      c16 = ts(c1,STAFFLOC) + vpar20 * 2 + 1 / vpar(2) - 20
                      c2 = 23 - c16

                      c4 = 200
                      c12 = ts(c1,AX) & 0x0f
                      c14 = c2 - int("221002200100001"{c12})    /* lower limit
                      c15 = c2 + int("333003300200003"{c12})    /* upper limit

                      loop for c3 = c14 to c15
                        if c3 > 0 and c3 <= 45
                          if gl(c13,c3) <= 0
                            c3 = 1000
                          else
                            if gl(c13,c3) < c4
                              c4 = gl(c13,c3)
                            end
                          end
                        end
                      repeat
                      if c3 < 1000
                        c3 = ts(c1,AX) & 0x0f
                        if ts(c1,TYPE) > REST
                          c4 = CUESIZE
                        else
                          c4 = bit(16,ts(c1,SUBFLAG_1))
                        end
                        perform place_accidental (c13,c2,c3,c4) /* returns c4 = absolute x
                        ts(c1,AX_DISP) = c3  /* capture this parameter, from place_accidental

                        c3 = ts(c1,GLOBAL_XOFF)
                        if c3 > INT10000
                          c3 /= INT10000              /* index of top of chord
                          c3 = ts(c3,GLOBAL_XOFF)
                        end
                        c6 = c3 - c4   /* relative x offset (to the left)
                  /* shift offset left 8 and OR with AX
                        c6 <<= 8                       /* 02/25/97 shift changed from 4 to 8
                        ts(c1,AX) |= c6
                        ndata(c8,c13) = DUMMY_VALUE    /* accidental set
                      end
QQQ1:
                    repeat
 
         (3) Now make successive passes until all accidentals are set

                    c10 = DOWN
                    loop
                      c6 = 0
                      loop for c8 = 1 to tgroup(c13)
                        if ndata(c8,c13) <> DUMMY_VALUE    /* accidental not set
                          c6 = c8
                        end
                      repeat
                      if c6 = 0
                        goto QQQ2                          /* DONE
                      end
                      if c10 = DOWN
                        c11 = 1
                        c12 = tgroup(c13)
                        c9 = 1
                      else
                        c11 = tgroup(c13)
                        c12 = 1
                        c9 = -1
                      end
                      c10 = UP
                      loop for c8 = c11 to c12 step c9
                        c1 = ndata(c8,c13)
                        if c1 = DUMMY_VALUE
                          goto QQQ3
                        end
                        if c8 > 1
                          c2 = ndata(c8-1,c13)
                          if c2 < DUMMY_VALUE
                            if ts(c1,STAFFLOC) - ts(c2,STAFFLOC) = vpar(1)  /* second
                            c16 = ts(c1,STAFFLOC) - ts(c2,STAFFLOC)
                            if c16 = vpar(1) or c16 = vpar(1) + 1           /* second
                              if ts(c1,LOCAL_XOFF) < ts(c2,LOCAL_XOFF)
                                /* don't set accidental in this situation
                                goto QQQ3
                              end
                            end
                          end
                        end
                        if c8 = c6
                          c10 = DOWN
                        end
                        c2 = 0 - ts(c1,STAFFLOC) / vpar(1) + 23
                        c16 = ts(c1,STAFFLOC) + vpar20 * 2 + 1 / vpar(2) - 20
                        c2 = 23 - c16

                        c3 = ts(c1,AX) & 0x0f
                        if ts(c1,TYPE) > REST
                          c4 = CUESIZE
                        else
                          c4 = bit(16,ts(c1,SUBFLAG_1))
                        end
                        perform place_accidental (c13,c2,c3,c4) /* returns c4 = absolute x
                        ts(c1,AX_DISP) = c3  /* capture this parameter, from place_accidental

                        c3 = ts(c1,GLOBAL_XOFF)
                        if c3 > INT10000
                          c3 /= INT10000              /* index of top of chord
                          c3 = ts(c3,GLOBAL_XOFF)
                        end
                        c15 = c3 - c4   /* relative x offset (to the left)
                  /* shift offset left 8 and OR with AX
                        c15 <<= 8                   /* 02/25/97 shift changed from 4 to 8
                        ts(c1,AX) |= c15
                        ndata(c8,c13) = DUMMY_VALUE    /* accidental set

QQQ3:
                      repeat
                    repeat
QQQ2:
                  end
                end
              repeat
            end

    Task (1)         Calculate NODE_SHIFT
 
            c10 = 0

            if c17 = 0                       /* set above

              loop for a3 = 1 to nstaves
                loop for c11 = 1 to 45
                  if gl(a3,c11) > pseudo_gl(a3,c11)
                    gl(a3,c11) = pseudo_gl(a3,c11)
                  end

               11/19/07 min_space replaces hpar(29)

                  c12 = min_space - gl(a3,c11) - emptyspace(a3,c11) /* should be negative

                  if c11 >= 14 and c11 <= 22
                    dputc Sorry  c12 = ~c12
                    putc     gl(~a3 ,~c11 ) = ~gl(a3,c11)
                    putc     emptyspace(~a3 ,~c11 ) = ~emptyspace(a3,c11)
                  end

                  if c12 > c10                                      /* most of the time
                    c10 = c12
                  end
                repeat
              repeat
              if c5 > 0 and ts(a1,SPACING) = mindist and c10 < hpar(94)
                c10 = hpar(94)
              end

            else



      More code from the 04/19/08 cludge
      This section uses the single-track formula to compute the
      value of this nodes NODE_SHIFT.

              loop for a3 = 1 to nstaves
                c7 = 100000
                loop for c11 = 1 to 45
                  if emptyspace(a3,c11) < c7
                    c7 = emptyspace(a3,c11)        /* minimum emptyspace on this staff
                  end
                repeat
                c10 = mindist - hpar(82) - c7
              repeat



            end


            dputc Value of c10 is ~c10

            if c10 > 0
              ts(a1,NODE_SHIFT) = c10
            end
    Task (2)
            c10 = ts(a1,SPACING)

            dputc     spacing = ~c10

            loop for a3 = 1 to nstaves
              loop for c6 = 1 to 45
                if pseudo_gr(a3,c6) > gr(a3,c6)
                  gr(a3,c6) = pseudo_gr(a3,c6)
                end
                if gr(a3,c6) = -200
                  emptyspace(a3,c6) += c10
                else
                  emptyspace(a3,c6) = c10 - gr(a3,c6)
                end

                if c6 >= 19 and c6 <= 21
                  dputc     gr(1,~c6 ) = ~gr(1,c6)
                  dputc     emptyspace(1,~c6 ) = ~emptyspace(1,c6)
                end

              repeat
            repeat

  ╔═══════════════════════════════════════════════════════════════╗
                                                                 
     End of where you deal with chords and with multiple passes  
                                                                 
  ╚═══════════════════════════════════════════════════════════════╝

          end
MMMMM:

      We need to check (for now) if the present simultaneity generates
      a "clash" with the previous simultaneity.

          if olda1 > 0
            c6 = -1000
            loop for c3 = 1 to 2
              loop for c4 = 1 to 45
                c5 = oldgr(c3,c4) - gl(c3,c4)
                if c5 > c6
                  c6 = c5
                end
              repeat
            repeat
            if c6 > ts(olda1,SPACING) + ts(olda1,NODE_SHIFT)
              putc Potential clash, possible program error
            end
          end
          loop for c3 = 1 to 2
            loop for c4 = 1 to 45
              oldgr(c3,c4) = gr(c3,c4)
            repeat
          repeat
          olda1 = a1
          a1 = a2
WWWW:
        repeat


   ╔═══════════════════════════════════════════════════════════════╗
                                                                  
      End of calculations on the placement of notes, note-dots,   
        and note-accidentals.                                     
                                                                  
   ╚═══════════════════════════════════════════════════════════════╝



 ***************************************************************
    Debug Information

        g = measnum - 1
        if bit(2,pmode) = 1 and g >= debug_point

     Condition changed 01/01/06

        if (bit(2,pmode) = 1 or debug_flag = 1) and g >= debug_point
          putc   Set Array at Point No. 3:  measure ~g
          putc Look?
          getc jtype
          if jtype = "y"
            perform display_ts
          end
        end

    End debug information
 ***************************************************************




   ╔════════════════════════════════════════════════════════════════════════╗
                                                                         
     At this point, we have a decision to make.  Either we process the   
     ts array now (i.e. typeset the music) or we return from this        
     procedure and let the ts array continue to grow.  The question that 
     must be answered is "will all outstanding slurs be processed when   
     the ts array is fully processed?"  If "yes", then we can go ahead   
     and process the ts array; otherwise, not.                           
                                                                         
     The information we need is contained in the SLUR_FLAG portion       
     of the ts array.  We need to cycle through the array elements we    
     have added, taking note of where slurs terminate and where they     
     start.  We need a variable to keep track of the state of slur       
     completion.  We call this variable bstr "outslurs".  The relevant   
     bits will be bits 1 to 8.  When a slur is initiated, the relevant   
     bit will be turned on; when a slur is terminated, the relevant      
     bit will be turned off.  If at the end of this process,             
     outslurs = "00000000", then we can process the array.               
                                                                         
   ╚════════════════════════════════════════════════════════════════════════╝

        loop for a1 = oldsct+1 to sct
          nodtype = ts(a1,TYPE)
          if nodtype <= NOTE_OR_REST
            a2 = ts(a1,SLUR_FLAG) & 0xff
            a3 = ts(a1,SLUR_FLAG) >> 8
            a3 &= 0xff00
            a3 += a2                  /* 16 bits, i.e., stop,start,stop,start etc.
            if a3 > 0
              a5 = 1
              loop for a4 = 1 to 8
                if bit(a5,a3) = 1
                  if outslurs{a4} = "0"    /* can't stop a non-existant slur
                    putc Slur error: Can't stop a non-existant slur (possible missing instigation)
                    stop
                  else
                    outslurs{a4} = "0"
                  end
                end
                --a5
                if bit(a5,a3) = 1
                  if outslurs{a4} = "1"    /* can't start an existing slur
                    putc Slur error: Can't start an existing slur (possible missing termination)
                    stop
                  else
                    outslurs{a4} = "1"
                  end
                end
                a5 += 3
              repeat
            end
          end
        repeat
        if outslurs <> "00000000"
          return
        end

    At this point we will be working with the entire ts array.  First
    thing, we must clear the pseudo tiearr ROWs.

        loop for c7 = 1 to MAX_TIES
          if tiearr(c7,TIE_SNUM) = INT1000000       /* pseudo super number
            tiearr(c7,TIE_SNUM) = 0
          end
        repeat

     Slur Analysis

     We am now in a position to compile complete information on slurs,
     so that they can more or less be set properly.  We possess the
     following information for the notes on which the slur starts and
     ends:
 
       (1) pitch (also whether it is part of a chord, also top or not)
       (2) stem direction (dist from end of stem, also if beam connects)
       (3) pass number
       (4) staff number
       (5) values of mcat and MULTI
 
     In addition, we need to compile the following information for each
     slur:
 
       (1) the "high point" and "low point" for all objects on the
            slur staff between the starting and ending notes.
 
     Based on this analysis, it should be possible to state:
 
       (1) whether the slur has tips up or down
 
       (2) the x-shift and y-shift for the start of the slur
 
       (3) the x-shift and y-shift for the end of the slur
 
       (4) any extra curviture that might help the situation
 
     In computing the parameters in (2), (3) and (4), it may be helpful
     to something about the profile of the desired slur.   For example:
 
         *                *               *     * * * * * *     * * * *
        *    *          *   *         *    *    *         *   *         *
       *  1.    *    *    2.   *   *    3.  *   *    4.   *   *    5.   *
       raise start   raise both     raise end    raise both     add to
                        some                       a lot       curviture
 
     Storage of Information
 
     We need to figure out where we are going to store this information.
     The way this program is constructed, it is possible (in theory at
     least) for eight slurs to end and for eight slurs to start on the
     same note.  This could require as many as 32 separate parameters
     at one ts(.,.) element, to say nothing about the 16 curviture
     numbers, which must be stored somewhere.  Rather than extend the
     size of the second dimension of the ts array by this amount, I
     would rather propose that we add one more element, call it
     SLUR_X, which would be a pointer to an additional ROW element in the
     ts array, somewhere below sct (the size of ts, after all, must be
     much larger than necessary, in order to accommodate 99.99% of all
     situations).

     While it is possible for eight slurs (four regular and four editorial)
     to start or end on one chord, I think it is unlikely that more than
     four would do so.  I would therefore propose that we use a system of
     flags to define the meaning of a data element within the ROW.  As
     will be explained below, the first 6 elements of the ROW are reserved
     for current information about the chord generating the slur, and after
     this, elements 7 to 32 can be used to hold data on slurs.  We will
     need to use two elements to contain all of the data.  Let us establish
     the convention that the first element will contain the key to the
     meaning of data as well as the type of slur (tips up/down), extra
     information on curvature, and the x-offset.  Specifically, the key
     will occupy bits 24-27, with the slur number (1-8) being stored in
     bits 24-26, and bit 27 being the the start/end flag (0 = start,
     1 = end).  Bit 16 will be the up/down flag (0 = tips up, 1 = tips
     down) and bits 17-23 will contain information on extra curvature
     (this information is necessary only in a slur-end element).  Bits
     0-15 will contain the x-offset + 1000 (always a positive number).
     The second element will contain the absolute y-position.  Since
     there are 26 free elements in the ROW, we can accommodate 13 data
     groups in this fashion (surely more than necessary).

     Several points to note:

     (1) for purposes of these calculations, and temporary data stroage,
         it will be simplest to record all y values as absolute y positions
         (relative to the staff lines).  x values can be stored as offsets.

     (2) In cases where more than one slur starts on a note head, or more
         than one slur ends on a note head, care must be taken to insure
         that the "longer" slur stays "on top" (assuming they have tips
         going in the same direction).  Let's take the situation pictured
         below:

                     * * * * * * * * slur 1 * * * * * * * *
                 *                                           *          slur 1a
              *                          * * * * slur 2 * * *  *      *
            *  * slur 4 *             * * slur 3 *             * *  *
           **             *         **             *             ***
         note 1         note 2    note 3        note 4          note 5
 
         Slur 1 would be encountered first as we proceeded through the ts
         array.  If we were to try to process this slur when we first
         encountered it, we would discover that another slur (slur 2)
         ended on the same note as slur 1.  Since slur 2 is shorter than
         slur 1, (and therefore should lie "under" it), we cannot fully
         process slur 1 until we have processed slur 2.  But in looking back
         to the beginning of slur 2, we see that another slur (slur 3) also
         starts on the same note, and that slur 3 (which also we have not
         seen before) must be processed before we can process slur 2.
         Clearly we cannot simply follow the rule of "process a slur when
         you first come to it".  A similar argument can be used to show
         that you cannot simply work your way through the ts array from
         end to the start.
 
         Here is how the process must be conducted:  You proceed forward
         though the ts array, but do nothing until you encounter the end
         of a slur (or more than one end, as in the case of note 5 above).
         If there is more than one slur ending on this note (chord), you can
         determine which one is shorter by looking backward in the array.
         The shorter one should be processed first.  In this way, you can
         always be sure that shorter slurs will be processed before longer
         ones.

         This method will require extra work in keeping track of what has
         already been done.  This is the purpose of the first 6 elements of
         the extra ts ROW element.  In our example above, slur 4 will be the
         first to be processed.  Since it is the first slur for both note 1
         and note 2, SLUR_X records must be generated for both of these
         notes.  In the case of note 2, this is the only slur, but for note 1
         we will be processing another slur (slur 1) much later.  We need
         to keep track of what has already transpired as a result of slur 4.
         The first 6 elements of the SLUR_X ROW element will contain the
         information listed below:
 
           (1) current y-position above object for incoming slurs.
           (2)              "     below   "     "     "       "  .
           (3)              "     above   "     "  outgoing   "  .
           (4)              "     below   "     "     "       "  .
           (5) y-position for staccato, legato, etc.
           (6) 2 = marks above chord; 1 = marks below chord; 0 = don't use

         Clearly, the information about what has happened at note 1 will
         be available when it comes time to set slur 1.

         One more thing: in handling this problem, we must deal with a chord
         as one object.  A chord may be made up of several elements (notes),
         and slurs coming to or leaving this chord may be coded on separate
         elements.  Nevertheless, the processing of information requires
         that all data related to slurs be stored in one place.  Therefore,
         when a slur ROW element is allocated, the pointer to the element
         must be put in SLUR_X for all notes in the chord.
 
     (3) It should be noted that the smallest meaningful resolution of a
         y-position as far as slurs are concerned is vpar(1), since the
         printing program treats these shifts as adjusted note positions.
 
     (4) The curvature parameter should be a number from 0 to 9 (9 being
         the most curved).  The printing program actually uses a look-up
         method to determine which slur to put in a particular position.
         One of the characterizations of such a slur is its curvature
         (this is part of the slur number).  It only makes sense to change
         this number if the new curvature is more than the "look up"
         value.  Since increasing the curvature will put the "cross part"
         of the slur at a different height, a new curvature should only
         be suggested in those cases where it is thought that the slur
         will not be interfering with staff lines.  One other thing:
         we do not know the final length of the slur until print time.
         It turns out that for slurs longer than a certain length
         (I think about .6 inches) there are varients available which
         are asymmetric (where the relative high point comes either
         earlier or later in the slur).  It is possible to "make a
         suggestion" to the print program that an asymmetric slur
         be used, if one is available.  Adding 10 to the curvature
         will suggest that the high point be delayed; and adding 20
         to the curvature will suggest that the high point come
         earlier.  Actually, as I remember it, slurs longer about 1.3
         inches only come in asymmetric versions, so for slurs that
         appear to be really long (either many notes, or multiple
         measures), it might actually be helpful to make a recommendation.
 
                  S U M M A R Y   O F   I N F O R M A T I O N   (TS32)
                  ───────────────────────────────────────────
 
     1. A slur is processed when its end is encountered.  If there is more
        than one slur on a chord, the shortest one is processed first.  If
        more than one of the same length is encountered, the one on the
        lowest note is processed first.
 
     2. The first time a slur is encountered on a chord, a new ts ROW
        element is allocated and a pointer to it is placed in the SLUR_X
        element for all notes in the chord.
 
     3. The first six elements of a slur ROW element are reserved for the
        following information:
 
           (1) current y-position above object for incoming slurs.
           (2)              "     below   "     "     "       "  .
           (3)              "     above   "     "  outgoing   "  .
           (4)              "     below   "     "     "       "  .
           (5) y-position for staccato, legato, etc.
           (6) 2 = marks above chord; 1 = marks below chord; 0 = don't use
 
     4. Specific information about slurs coming to or leaving a chord is
        stored in groups of three (up from two 05/06/03) elements, starting
        with element 7.  The format is as follows:
 
        first element
        ────────────────────
           bit 27:     start/end flag (0 = start, 1 = end)
           bits 24-26: slur number - 1 (0 to 7)
           bits 17-23: curvature information (end only)
           bit 16:     up/down flag (0 = tips up, 1 = tips down) (end only)
           bits 0-15:  x-offset + 1000 (always a positive number)
        second element
        ─────────────────────
           y position relative to the staff
        third element (added 05/06/03)
        ─────────────────────
           integer equivalent of 4-byte print suggestion for slur
 


             ┌─────────────────────────────────────────┐
                                                  
              P R O C E S S I N G    S L U R S    
                                                  
             └─────────────────────────────────────────┘


        a14 = sct + 2                   /* SLUR_X pointer

        loop for a1 = 1 to sct
          nodtype = ts(a1,TYPE)
          if nodtype > NOTE_OR_REST
            goto YYYY
          end
          a4 = ts(a1,SLUR_FLAG) & 0x00aa00aa
          if a4 > 0                     /* a slur ends here

      Compile a list of all slurs that end on this note and on any
        other (lower) notes in this chord.

            a5 = a4 >> 1
            a5 &= 0x00ff00ff            /* a list of starts to look for
            ndata(1,1) = a5
            ndata(1,2) = a1
            pcnt = 1
            perform get_topbottom (a1,c1,c2)
            loop for a2 = a1+1 to c2
              a4 = ts(a2,SLUR_FLAG) & 0x00aa00aa
              if a4 > 0                 /* a slur ends here
                a5 = a4 >> 1
                a5 &= 0x00ff00ff        /* a list of starts to look for
                ++pcnt
                ndata(pcnt,1) = a5
                ndata(pcnt,2) = a2
              end
            repeat
            a1 = c2       /* so that we don't look at these notes again


            examine       /*  09/28/93


            nsgroups = 0
            c9 = pcnt                            /* moved here from +3 lines 09/28/93
            loop for c7 = c1-1 to 1 step -1
              if ts(c7,TYPE) <= NOTE_OR_REST
                a6 = ts(c7,SLUR_FLAG) & 0x00550055   /* starts on this note
                loop for c8 = 1 to pcnt
                  a5 = ndata(c8,1)            /* list of starts for this note of chord
                  a2 = ndata(c8,2)            /* index to this note of chord
                  a7 = a6 & a5                /* a7 = matches
                  if a7 > 0

                    if a7 & 0x00100010 > 0
    This code         a2 |= 0x00010000        /* this is a "force over" slur
   must be          else
   changed            if a7 & 0x00400040 > 0
   to below             a2 |= 0x00020000      /* this is a "force under" slur
   10-09-93           end
                    end

                    c11 = a7 >> 8
                    c11 &= 0xff00
                    c11 += a7 & 0xff                 /* compact a7 into 16 bits

                    a7 = not(a7)
                    a5 &= a7                         /* remove this slur from a5
                    ndata(c8,1) = a5

                    c10 = 0                   /* slur number - 1
                    c6 = a2
                    loop while c11 > 0
                      if bit(0,c11) = 1
                        c4 = c10 & 0x03              /* slur number mod(4)
                        c5 = 1 << (c4 * 2)
                        c5 <<= 8
                        if c5 & ts(c7,SLUR_FLAG) > 0   /* this slur is forced
                          c5 <<= 1
                          if c5 & ts(c7,SLUR_FLAG) = 0
                            c6 |= 0x00010000      /* this is a "force over" slur
                          else
                            c6 |= 0x00020000      /* this is a "force under" slur
                          end
                        end
                        ++nsgroups
                        sgroup(nsgroups,1) = c7   /* record index starting note
                        sgroup(nsgroups,2) = c6   /* record index ending note (+ flags)
                        sgroup(nsgroups,3) = c10  /* slur number - 1
                      end
                      c11 >>= 2
                      ++c10
                    repeat

                    if a5 = 0
                      --c9
                      if c9 = 0         /* no more slurs to look for
                        c7 = 0
                      end
                    end
                  end
                repeat
              end
            repeat
            if nsgroups = 0 or c9 > 0
              putc Can't find start to a slur
              examine
              stop
            end
 
      At this point, we have a list of slurs which end on this chord.
      We need to decide what to do with them.  We certainly can proceed
      by looping though the group, but we should probably first learn
      something about the chords we are dealing with.  For example,
      is the stem up or down?  Where on the chords do the slurs attach?
      Do the note heads (or chords) have staccato, legato or spiccato
      marks on them?  (Remember that the notes of a chord have been
      re-ordered so that the top note comes first; i.e., the top note
      head may not be at the note end of the stem.)   The purpose of
      all of this "research" is basically to answer the following
      two questions:

         (1) should the slur be oriented with tips up or tips down, and

         (2) should the slur take its position from the note head or
               from the end of the stem?

      I think I have found a system which will at least (1) give an answer
      to every possible situation, and (2) give "right" answers for most
      situations.  Essentially, what I will use is "situation based"
      programming, rather than "rule based" programming.  I have described
      all possible situations under two conditions: (1) the final note
      has the multi-track flag = 0, and (2) the final note has the multi-track
      flag > 0.  These templates are laid out below

  I. Final note multi-track flag = 0

   starting note            ending note        x-shift stem option           overrides
  stem  position         stem   position  tips 1st 2nd 1st 2nd          code over under
  ──────────────         ────────────────┬────┬───────┬────────────────┬────┬────┬────┬
  up    single        up     single      │ up │H    H │  no            │  F │  l │  F │
  (multi-track = 0)   up    top of many  │down│  no   │s    s          │  p │  p │  G │
                      up  middle of many │down│nr   Y │  no            │  m │  p │  H │
                      up  bottom of many │ up │H    H │  no            │  F │  p │  F │
                     down    single      │down│nr   H │s    H (if flag)│  j │  j │  I │
                     down   top of many  │down│  no   │s    H          │  o │  o │  G │
                     down middle of many │down│nr   H │                │  i │  i │  O │
                     down bottom of many │ up │  no   │H    s          │  O │  o │  O │
                                         │    │       │                │    │    │    │
  up    single        up     single      │down│nr   H │s    s (mid stf)│  l │  l │  F │
  (multi-track > 0)   up    top of many  │down│  no   │s    s          │  p │  p │  G │
                      up  middle of many │down│nr   Y │  no            │  m │  p │  H │
                      up  bottom of many │ up │H    H │  no            │  F │  p │  F │
                     down    single      │down│  no   │s    H          │  o │  j │  I │
                     down   top of many  │down│  no   │s    H          │  o │  o │  G │
                     down middle of many │down│nr   H │                │  i │  i │  O │
                     down bottom of many │ up │  no   │H    s          │  O │  o │  O │
                                         │    │       │                │    │    │    │
  up   top of many    up     single      │down│  no   │s    s          │  p │  p │  F │
  (multi-track = 0)   up    top of many  │down│nr   n │s    s (no oths)│  h │  h │  N │
  (multi-track > 0)   up  middle of many │down│  no   │s    s          │  p │  p │  F │
                      up  bottom of many │ up │H    H │  no            │  F │  p │  F │
                     down    single      │down│  no   │s    H          │  o │  o │  I │
                     down   top of many  │down│nr   H │s    H (no oths)│  k │  k │  N │
                     down middle of many │down│  no   │s    H          │  o │  o │  G │
                     down bottom of many │down│nr   H │  no            │  i │  i │  G │
                                         │    │       │                │    │    │    │
  up middle of many   up     single      │down│Yr   n │  no            │  f │  f │  F │
  (multi-track = 0)   up    top of many  │down│Yr   n │  no            │  f │  f │  F │
  (multi-track > 0)   up  middle of many │down│nr   nl│  no            │  n │  n │  N │
                      up  bottom of many │ up │H    H │  no            │  F │  r │  F │
                     down    single      │down│Yr   H │  no            │  g │  g │  I │
                     down   top of many  │down│Yr   H │  no            │  g │  g │  G │
                     down middle of many │down│nr   nl│  no            │  n │  n │  N │
                     down bottom of many │ up │H    nl│  no            │  H │  g │  H │
                                         │    │       │                │    │    │    │
  up botton of many   up     single      │ up │H    H │  no            │  F │  f │  F │
  (multi-track = 0)   up    top of many  │down│Yr   n │  no            │  f │  f │  F │
  (multi-track > 0)   up  middle of many │ up │H    H │  no            │  F │  s │  F │
                      up  bottom of many │ up │H    H │  no            │  F │  n │  F │
                     down    single      │ up │H    nl│H    s (positio)│  I │  g │  I │
                     down   top of many  │down│Yr   H │  no            │  g │  g │  G │
                     down middle of many │ up │H    Yl│                │  G │  g │  G │
                     down bottom of many │ up │H    nl│H    s (p n oth)│  J │  n │  J │
                                         │    │       │                │    │    │    │
  down  single        up     single      │down│H    n │H    s (positio)│  c │  c │  B │
  (multi-track = 0)   up    top of many  │down│H    n │H    s (positio)│  c │  c │  B │
                      up  middle of many │down│H    Y │  no            │  e │  e │  B │
                      up  bottom of many │ up │n    H │s    H (positio)│  B │  e │  B │
                     down    single      │down│H    H │  no            │  d │  d │  E │
                     down   top of many  │down│H    H │  no            │  d │  d │  C │
                     down middle of many │down│H    H │  no            │  d │  d │  C │
                     down bottom of many │ up │  no   │s    s          │  Q │  d │  Q │
                                         │    │       │                │    │    │    │
  down  single        up     single      │ up │n    H │s    H (positio)│  B │  c │  B │
  (multi-track > 0)   up    top of many  │down│H    n │  no            │  a │  c │  B │
                      up  middle of many │ up │n    H │  no            │  A │  e │  B │
                      up  bottom of many │ up │  no   │s    H          │  P │  e │  B │
                     down    single      │ up │n    nl│s    s (mid stf)│  E │  d │  E │
                     down   top of many  │down│H    H │  no            │  d │  d │  C │
                     down middle of many │ up │  no   │s    s          │  Q │  d │  C │
                     down bottom of many │ up │  no   │s    s          │  Q │  d │  Q │
                                         │    │       │                │    │    │    │
  down  top of many   up     single      │down│H    n │H    s (positio)│  c │  c │  K │
  (multi-track = 0)   up    top of many  │down│H    n │H    s (p n oth)│  b │  b │  C │
  (multi-track > 0)   up  middle of many │down│H    Y │  no            │  e │  e │  K │
                      up  bottom of many │down│H    Y │  no            │  e │  e │  K │
                     down    single      │down│H    H │  no            │  d │  d │  Q │
                     down   top of many  │down│H    H │  no            │  d │  d │  N │
                     down middle of many │down│H    H │  no            │  d │  d │  L │
                     down bottom of many │ up │Y    nl│  no            │  M │  d │  M │
                                         │    │       │                │    │    │    │
  down middle of many up     single      │ up │Y    H │  no            │  K │  c │  K │
  (multi-track = 0)   up    top of many  │down│H    n │  no            │  a │  a │  K │
  (multi-track > 0)   up  middle of many │ up │nr   nl│  no            │  N │  n │  N │
                      up  bottom of many │ up │Y    H │  no            │  K │  a │  K │
                     down    single      │down│H    H │  no            │  d │  d │  M │
                     down   top of many  │down│H    H │  no            │  d │  d │  L │
                     down middle of many │ up │nr   nl│  no            │  N │  n │  N │
                     down bottom of many │ up │Y    nl│  no            │  M │  d │  M │
                                         │    │       │                │    │    │    │
  down bottom of many up     single      │ up │n    H │s    H (positio)│  B │  c │  B │
  (multi-track = 0)   up    top of many  │down│H    n │  no            │  a │  a │  K │
  (multi-track > 0)   up  middle of many │ up │n    H │  no            │  A │  e │  A │
                      up  bottom of many │ up │n    H │  no            │  A │  n │  A │
                     down    single      │ up │n    nl│s    s (mid stf)│  E │  d │  E │
                     down   top of many  │ up │n    Yl│  no            │  C │  d │  C │
                     down middle of many │ up │n    Yl│  no            │  C │  d │  C │
                     down bottom of many │ up │n    nl│s    s (no oths)│  D │  n │  D │


  II. Final note multi-track flag > 0

   starting note            ending note        x-shift stem option              (same)
  stem  position         stem   position  tips 1st 2nd 1st 2nd          code  (overrides)
  ──────────────         ────────────────┬────┬───────┬────────────────┬────┬
  up    single        up     single      │down│nr   H │s    s (mid stf)│  l │
  (multi-track = 0)   up    top of many  │down│  no   │s    s          │  p │
                      up  middle of many │down│nr   Y │  no            │  m │
                      up  bottom of many │ up │H    H │  no            │  F │
                     down    single      │ up │H    nl│H    s (positio)│  I │
                     down   top of many  │ up │H    Yl│  no            │  G │
                     down middle of many │ up │H    Yl│  no            │  G │
                     down bottom of many │ up │  no   │H    s          │  O │
                                         │    │       │                │    │
  up    single        up     single      │down│nr   H │s    s (mid stf)│  l │
  (multi-track > 0)   up    top of many  │down│  no   │s    s          │  p │
                      up  middle of many │down│nr   Y │  no            │  m │
                      up  bottom of many │ up │H    H │  no            │  F │
                     down    single      │ up │  no   │H    s          │  O │
                     down   top of many  │ up │H    Yl│  no            │  G │
                     down middle of many │ up │  no   │H    s          │  O │
                     down bottom of many │ up │  no   │H    s          │  O │
                                         │    │       │                │    │
  up   top of many    up     single      │down│  no   │s    s          │  p │
  (multi-track = 0)   up    top of many  │down│nr   n │s    s (no oths)│  h │
  (multi-track > 0)   up  middle of many │down│  no   │s    s          │  p │
                      up  bottom of many │ up │H    H │  no            │  F │
                     down    single      │down│  no   │s    H          │  o │
                     down   top of many  │down│nr   H │  no            │  i │
                     down middle of many │ up │H    Yl│  no            │  G │
                     down bottom of many │ up │H    nl│  no            │  H │
                                         │    │       │                │    │
  up middle of many   up     single      │down│Yr   n │  no            │  f │
  (multi-track = 0)   up    top of many  │down│Yr   n │  no            │  f │
  (multi-track > 0)   up  middle of many │down│nr   nl│  no            │  n │
                      up  bottom of many │ up │H    H │  no            │  F │
                     down    single      │down│Yr   H │  no            │  g │
                     down   top of many  │down│Yr   H │  no            │  g │
                     down middle of many │ up │nr   nl│  no            │  N │
                     down bottom of many │ up │H    nl│  no            │  H │
                                         │    │       │                │    │
  up botton of many   up     single      │ up │H    H │  no            │  F │
  (multi-track = 0)   up    top of many  │down│Yr   n │  no            │  f │
  (multi-track > 0)   up  middle of many │ up │H    H │  no            │  F │
                      up  bottom of many │ up │H    H │  no            │  F │
                     down    single      │ up │H    nl│H    s (positio)│  I │
                     down   top of many  │down│Yr   H │  no            │  g │
                     down middle of many │ up │H    Yl│  no            │  G │
                     down bottom of many │ up │H    nl│H    s (p n oth)│  J │
                                         │    │       │                │    │
  down   single       up     single      │down│H    n │H    s (positio)│  c │
  (multi-track = 0)   up    top of many  │down│H    n │H    s (positio)│  c │
                      up  middle of many │down│H    Y │  no            │  e │
                      up  bottom of many │ up │n    H │s    H (positio)│  B │
                     down    single      │ up │n    nl│s    s (mid stf)│  E │
                     down   top of many  │ up │n    Yl│  no            │  C │
                     down middle of many │ up │  no   │s    s          │  Q │
                     down bottom of many │ up │  no   │s    s          │  Q │
                                         │    │       │                │    │
  down   single       up     single      │down│H    n │H    s (positin)│  c │
  (multi-track > 0)   up    top of many  │down│H    H │  no            │  d │
                      up  middle of many │down│H    Y │  no            │  e │
                      up  bottom of many │ up │n    H │  no            │  A │
                     down    single      │ up │n    nl│s    s (mid stf)│  E │
                     down   top of many  │ up │n    Yl│  no            │  C │
                     down middle of many │ up │  no   │s    s          │  Q │
                     down bottom of many │ up │  no   │s    s          │  Q │
                                         │    │       │                │    │
  down  top of many   up     single      │down│H    n │H    s (positio)│  c │
  (multi-track = 0)   up    top of many  │down│H    n │H    s (p n oth)│  b │
  (multi-track > 0)   up  middle of many │down│H    Y │  no            │  e │
                      up  bottom of many │down│H    Y │  no            │  e │
                     down    single      │down│H    H │  no            │  d │
                     down   top of many  │down│H    H │  no            │  d │
                     down middle of many │ up │Y    Yl│  no            │  L │
                     down bottom of many │ up │Y    nl│  no            │  M │
                                         │    │       │                │    │
  down middle of many up     single      │ up │Y    H │  no            │  K │
  (multi-track = 0)   up    top of many  │down│H    n │  no            │  a │
  (multi-track > 0)   up  middle of many │ up │nr   nl│  no            │  N │
                      up  bottom of many │ up │Y    H │  no            │  K │
                     down    single      │ up │Y    nl│  no            │  M │
                     down   top of many  │down│H    H │  no            │  d │
                     down middle of many │ up │nr   nl│  no            │  N │
                     down bottom of many │ up │Y    nl│  no            │  M │
                                         │    │       │                │    │
  down bottom of many up     single      │ up │n    H │  no            │  A │
  (multi-track = 0)   up    top of many  │down│H    n │  no            │  a │
  (multi-track > 0)   up  middle of many │ up │n    H │  no            │  A │
                      up  bottom of many │ up │n    H │  no            │  A │
                     down    single      │ up │n    nl│s    s (mid stf)│  E │
                     down   top of many  │ up │n    Yl│  no            │  C │
                     down middle of many │ up │n    Yl│  no            │  C │
                     down bottom of many │ up │n    nl│s    s (p n oth)│  D │


                             Meaning of codes
                 ───────────────────────────────────────

                            x-shift    stem option
             code   tips    1st  2nd    1st  2nd
             ───── ──────  ──────────  ───────────
               A     up      n    H        no
               B     up      n    H      s    H (position)
               C     up      n    Yl       no
               D     up      n    nl     s    s (no others)
               E     up      n    nl     s    s (mid stuff)
               F     up      H    H        no
               G     up      H    Yl       no
               H     up      H    nl       no
               I     up      H    nl     H    s (position)
               J     up      H    nl     H    s (pos no oth)
               K     up      Y    H        no
               L     up      Y    Yl       no
               M     up      Y    nl       no
               N     up      nr   nl       no
               O     up        no        H    s
               P     up        no        s    H
               Q     up        no        s    s

               a    down     H    n        no
               b    down     H    n      H    s (pos no oth)
               c    down     H    n      H    s (position)
               d    down     H    H        no
               e    down     H    Y        no
               f    down     Yr   n        no
               g    down     Yr   H        no
               h    down     nr   n      s    s (no oths)
               i    down     nr   H        no
               j    down     nr   H      s    H (if flag)
               k    down     nr   H      s    H (no oths)
               l    down     nr   H      s    s (mid stuff)
               m    down     nr   Y        no
               n    down     nr   nl       no
               o    down       no        s    H
               p    down       no        s    s


                               Extra codes
                             Meaning of codes
                 ───────────────────────────────────────

                            x-shift     2nd option
             code   tips    1st  2nd    1st  2nd
             ───── ──────  ──────────  ───────────
               R     up      n    nl       no


               q    down     nr   n        no
               r    down     Yr   Yl       no
               s    down     Yr   Y        no
               t    down       no        H    s

      This information is combined into a 160 byte string.  By correctly
      diagnosing the situation, we can therefore determine what actions
      should be taken.  For both and starting note and the ending note
      we need to determine:

         (1) multi-track flag? (zero or non-zero)
         (2) stem direction?   (up or down)
         (3) note catagory?    (single, top of many,
                                middle of many, bottom of many)
 

           ╔════════════════════════════════════════════╗
           ║   This is the loop which processes slurs   ║
           ╚════════════════════════════════════════════╝

            loop for a4 = 1 to nsgroups   /* loop through all slurs ending on this chord

              examine

              a6 = sgroup(a4,1)
              a7 = sgroup(a4,2)
              c7 = a7 >> 16                   /* get forced slur flag
              a7 &= 0xffff                    /* clean up index

         1a. Get information on starting note

              c1 = multi-track flag for this note
              c2 = stem direction for this note
              c3 = note catagory for this note:  0 = single
                                                 1 = top of many
                                                 2 = middle of many
                                                 3 = bottom of many
              c7 = forced slur flag

              c1 = ts(a6,MULTI_TRACK) >> 2
              c2 = bit(1,ts(a6,STEM_FLAGS))
              c3 = bit(2,ts(a6,STEM_FLAGS))
              if c3 = 1 and bit(3,ts(a6,STEM_FLAGS)) = 1
                ++c3
                if ts(a6+1,TYPE) <> ts(a6,TYPE)
                  ++c3
                end
              end

         1b. Get information on ending note

              c4 = multi-track flag for this note
              c5 = stem direction for this note
              c6 = note catagory for this note:  0 = single
                                                 1 = top of many
                                                 2 = middle of many
                                                 3 = bottom of many

              c4 = ts(a7,MULTI_TRACK) >> 2
              c5 = bit(1,ts(a7,STEM_FLAGS))
              c6 = bit(2,ts(a7,STEM_FLAGS))
              if c6 = 1 and bit(3,ts(a7,STEM_FLAGS)) = 1
                ++c6
                if ts(a7+1,TYPE) <> ts(a7,TYPE)
                  ++c6
                end
              end

         1c. Modify multi-track flags under certain conditions

              if c1 > 0 and c4 > 0     /* CHANGED from = 3  on 9-10-93
                if ts(a6,PASSNUM) = ts(a7,PASSNUM) and c2 = c5
                  if ts(a6,PASSNUM) = 1 and c2 = DOWN
                    c1 = 0
                    c4 = 0
                  end
                  if ts(a6,PASSNUM) = 2 and c2 = UP
                    c1 = 0
                    c4 = 0
                  end
                end
              end

      2. Derive "situation" letter from c1 - c7.
 
              c8 = c3
              if c8 <> 0 or c1 <> 0
                ++c8
              end
              if c2 = DOWN
                c8 += 5
              end
              if c4 > 0 and c7 = 0
                c8 += 10
              end
              c8 *= 8                /* c8 ranges by 8's from 0 to 19*8
              c8 += c6
              if c5 = DOWN
                c8 += 4
              end
              ++c8                   /* c8 ranges from 1 to 160 (1 to 80 for forced slurs)
              if c7 = 0
                slurlet = slurstr{c8}
                if c1 = 0 and c4 = 0
                  if chr(ts(a6,TYPE)) in [GR_NOTE,XGR_NOTE]
                    if chr(ts(a7,TYPE)) in [NOTE,XNOTE]
                      slurlet = slurunder{c8}   /* force under
                    end
                  end
                end
              else
                if c7 = 1
                  slurlet = slurover{c8}    /* force over
                else
                  slurlet = slurunder{c8}   /* force under
                end
              end

      2a. Attempt to account for interfering beams

              if ts(a6,TYPE) < GR_NOTE or ts(a7,TYPE) > XNOTE
                if "abcIJijAB" con slurlet
                  if mpt < 6
                    c12 = ts(a7,BEAM_FLAG)
                    if c12 = CONT_BEAM or c12 = END_BEAM
                      if mpt < 4           /* down-up; tips down; modify end
                        slurlet = "t"
                      else                 /* up-down; tips up; modify end
                        slurlet = "O"
                      end
                    end
                  else
                    c12 = ts(a6,BEAM_FLAG)
                    if c12 = CONT_BEAM or c12 = START_BEAM
                      if mpt < 8           /* down-up; tips up; modify beginning
                        slurlet = "o"
                      else                 /* up-down; tips down; modify beginning
                        slurlet = "P"
                      end
                    end
                  end
                end
              end

      3. Decompose "compound" situations into separate "simple" situations

         (1) if code in [D,J,b,h,k], are there other slurs between the chords?
               If yes, then these codes become [R,H,a,q,i]

         (2) if code = I or J, is ending note vpar(6) higher than starting note?
               If yes, then these codes both become O, otherwise they become H

         (3) if code in [B,b,c], is ending note vpar(6) lower than starting note?
               If yes, then codes become [P,t,t]; otherwise they become [A,a,a]

         (4) if code = j, does starting note have a flag?  If yes, it becomes
                an "o".  Otherwise it is an "i"

         (5) if code = l or E, is there anything between the notes (chords)
                If yes, they become p and Q; otherwise they are i and R.

              if "DJbhk" con slurlet
                c12 = mpt
                perform get_topbottom (a6,c1,c2)
                perform get_topbottom (a7,c4,c5)

                if c2 > c1 and c5 > c4        /* both chords
                  loop for c3 = c1 to c2      /* first chord
                    if c3 <> a6

                  /* look for other slurs

                      c8 = ts(c3,SLUR_FLAG) & 0x00550055
                      if c8 > 0               /* slur(s) start(s)
                        c8 <<= 1              /* set of end flags for these slurs
                        loop for c9 = c2 + 1 to c5
                          c10 = ts(c9,TYPE)
                          if chr(c10) in [NOTE,XNOTE,CUE_NOTE,XCUE_NOTE,GR_NOTE,XGR_NOTE]
                            c11 = ts(c9,SLUR_FLAG) & c8
                            if c11 > 0    /* slur ends
                              if c9 >= c4 and c9 <> a7  /* condition met!
                                slurlet = "RHaqi"{c12}
                                goto SSEND1
                              else
                                c11 = not(c11)
                                c8 &= c11   /* turn off this possibility
                              end
                            end
                          end
                        repeat
                      end

                  /* now look for ties

                      if bit(0,ts(c3,SUPER_FLAG)) = 1
                        loop for c9 = c4 to c5
                          if c9 <> a7
                            c10 = ts(c9,BACKTIE)
                            if c10 = c3                 /* condition met!  (tricky code)
                              slurlet = "RHaqi"{c12}
                              goto SSEND1
                            end
                          end
                        repeat
                      end
                    end
                  repeat
                end
                slurlet = "QJbpo"{c12}
              end
SSEND1:
              c7 = 0              /* option flag

              if "IJBbcjlE" con slurlet
                c8 = ts(a6,BEAM_FLAG)
                c9 = ts(a7,BEAM_FLAG)
                goto SS(mpt)
SS(1):                            /* "IJ"
                if ts(a6,STAFFLOC) - ts(a7,STAFFLOC) > vpar(7)
                  c7 = 1
                end
                if ts(a6,TYPE) < GR_NOTE or ts(a7,TYPE) > XNOTE
                  if c9 = CONT_BEAM or c9 = END_BEAM
                    c7 = 1
                  end
                end
                goto SSEND
SS(3):                            /* "Bbc"
                if ts(a7,STAFFLOC) - ts(a6,STAFFLOC) > vpar(7)
                  if slurlet = "B"
                    c7 = 1
                  else                             /* (New 05/17/03)
                    if ts(a7,SUBFLAG_2) & 0x3c > 0 or ts(a7,ED_SUBFLAG_2) & 0x3c > 0
                      if ts(a7,STAFFLOC) - ts(a6,STAFFLOC) > vpar(9)
                        c7 = 1
                      end
                    else
                      c7 = 1
                    end
                  end
                end
                if mpt = 3
                  if c8 = START_BEAM or c8 = CONT_BEAM
                    c7 = 1
                  end
                else
                  if c9 = CONT_BEAM or c9 = END_BEAM
                    c7 = 1
                  end
                end
                goto SSEND
SS(6):                            /* "j"
                if c8 = NO_BEAM
                  if ts(a6,NTYPE) < QUARTER
                    c7 = 1
                  end
                else
                  if c8 = START_BEAM or c8 = CONT_BEAM
                    c7 = 1
                  end
                end
                goto SSEND
SS(7):                            /* "lE"   beams on both notes of slur?
                if c8 > NO_BEAM and c9 > NO_BEAM
                  slurlet = "      pQ"{mpt}
                end
                goto SSEND2

      At this point in the code, a1,a4,a6,a7 and a14 should not be changed

SSEND:

      Break 'm up
 
                if c7 = 1
                  slurlet = "OOPttopQ"{mpt}
                else
                  slurlet = "HHAaaiiR"{mpt}
                end
              end

      At this point, you have determined the "situation" letter for the
      between "a6" and "a7" (with the exception of the cases "l" and "E",
      which depend on the material between the slurs).  You now need to
      compile a profile of whatever material might be between the slurs
      on this staff. (organized by advancing division)

SSEND2:
              c12 = 0
              if "lE" con slurlet          /* we do cases "l" and "E" here
                c12 = mpt
                c3 = ts(a6,STAFFLOC)
                c4 = ts(a7,STAFFLOC)
                if c3 < c4
                  c3 = c4
                  c4 = ts(a6,STAFFLOC)
                end
                if mpt = 1
                  c4 -= vpar(4)
                else
                  c3 += vpar(4)
                end
              end
              c9 = 0
              c7 = 0
              c8 = ts(a7,STAFF_NUM)
              c15 = ts(a6,DIV)
              c10 = a7
              loop while chr(ts(c10,TYPE)) in [XNOTE,XCUE_NOTE,XGR_NOTE]
                --c10
              repeat
              --c10       /* c10 will not point to the last chord
              loop for c1 = a6+1 to c10
                if ts(c1,STAFF_NUM) = c8
                  nodtype = ts(c1,TYPE)
                  if chr(nodtype) in [NOTE,CUE_NOTE,GR_NOTE]
                    if bit(1,ts(c1,STEM_FLAGS)) = UP
                      c5 = ts(c1,VIRT_STEM)
                      c6 = ts(c1,VIRT_NOTE)
                    else
                      c5 = ts(c1,VIRT_NOTE)
                      c6 = ts(c1,VIRT_STEM)
                    end
                  else
                    if chr(nodtype) in [REST,CUE_REST]
                      c5 = ts(c1,STAFFLOC) - vpar(3)
                      c6 = ts(c1,STAFFLOC) + vpar(3)
                    else
                      if nodtype = CLEF_CHG
                        c5 = 0
                        c6 = vpar(8)
                      else

          11/26/06  Fixing a minor bug in the placement of slurs

                        c5 = 10000
                        if nodtype < METER_CHG
                          c5 = 1000
                          c6 = -1000
                        else
                          c5 = 10000
                        end
               End of 11/26/06 change
                      end
                    end
                  end
                  if c5 < 10000
                    if c12 > 0
                      if c3 > c5 and c4 < c6
                        c7 = 1
                      end
                    end
                    if ts(c1,DIV) <> c15
                      ++c9                             /*   Case 1:
                      profile(c9,1) = c5 - vpar(2)     /*     new division
                      profile(c9,2) = c6 + vpar(2)     /*
                    else
                      if c9 > 0
                        c5 -= vpar(2)                  /*   Case 2:
                        c6 += vpar(2)                  /*     more notes
                        if c5 < profile(c9,1)          /*     on same
                          profile(c9,1) = c5           /*     division
                        end                            /*
                        if c6 > profile(c9,2)
                          profile(c9,2) = c6
                        end
                      end
                    end
                  end
                end
                if ts(c1,TYPE) = BAR_LINE
                  c15 = 0
                else
                  c15 = ts(c1,DIV)
                end
              repeat
              if c12 > 0
                if c7 = 1
                  slurlet = "pQ"{c12}
                else
                  slurlet = "iR"{c12}
                end
              end

      More modifications to slurlet.  If there are staccatos, legatos,
      or spiccatos connected to the note head, then under certain
      conditions the slur must start at the stem of the note.

            /* New code rewritten 05/17/03

              c16 = ts(a6,SUBFLAG_2) | ts(a6,ED_SUBFLAG_2)   /* combination subflag_2 at a6
              c16 &= 0x3c                                    /* staccato, legato, etc.
              c17 = ts(a7,SUBFLAG_2) | ts(a7,ED_SUBFLAG_2)   /* combination subflag_2 at a7
              c17 &= 0x3c                                    /* staccato, legato, etc.

              if slurlet < chr(96)     /* tips up
                if c16 > 0
                  if bit(1,ts(a6,STEM_FLAGS)) = DOWN
                    if "ACRKLM" con slurlet
                      slurlet = "PQQPQQ"{mpt}
                    end
                  end
                end
                if ts(a6,TYPE) < GR_NOTE and c17 > 0
                  if bit(1,ts(a7,STEM_FLAGS)) = DOWN
                    if "CGHLMR" con slurlet
                      slurlet = "QOOQQQ"{mpt}
                    end
                  end
                end
              else                      /* tips down
                if c16 > 0
                  if bit(1,ts(a6,STEM_FLAGS)) = UP
                    if "fgimqrs" con slurlet
                      slurlet = "poopppp"{mpt}
                    end
                  end
                end
                if c17 > 0
                  if bit(1,ts(a7,STEM_FLAGS)) = UP
                    if slurlet = "o"
                      slurlet = "p"
                    end
                  end
                end
              end                         /* End of 05/17/03 rewrite

                 Updated list of letter codes
               ────────────────────────────────

        tips up           tips down            explanation
    code   1st  2nd    code   1st  2nd    letter        meaning
    ───── ──────────   ───── ──────────   ──────  ─────────────────
      A     n    H       a     H    n        n     note
      C     n    Yl      d     H    H        nr    start right of note
      F     H    H       e     H    Y        nl    end left of note
      G     H    Yl      f     Yr   n        H     head of chord
      H     H    nl      g     Yr   H        Y     position of object
      K     Y    H       i     nr   H              (opposite of H)
      L     Y    Yl      m     nr   Y        Yr    start right of object
      M     Y    nl      n     nr   nl       Yl    end left of object
      N     nr   nl      o     s    H        s     stem
      O     H    s       p     s    s
      P     s    H       q     nr   n
      Q     s    s       r     Yr   Yl
      R     n    nl      s     Yr   Y
                         t     H    s



      At this point, we need to check to see of this is the first time
      either chord has been touched by a slur.  When creating the
      slur element ROW, we need to write in the first four elements:

         (1) current y-position above object for incoming slurs.
         (2)              "     below   "     "     "       "  .
         (3)              "     above   "     "  outgoing   "  .
         (4)              "     below   "     "     "       "  .

              perform get_topbottom (a6,c1,c2)
              if ts(a6,SLUR_X) = 0
                ++a14
                loop for c8 = c1 to c2
                  ts(c8,SLUR_X) = a14
                repeat
                if bit(1,ts(a6,STEM_FLAGS)) = UP
                  ts(a14,1) = ts(a6,VIRT_STEM)
                  ts(a14,2) = ts(a6,VIRT_NOTE)
                  ts(a14,3) = ts(a6,VIRT_STEM)
                  ts(a14,4) = ts(a6,VIRT_NOTE)
                else
                  ts(a14,1) = ts(a6,VIRT_NOTE)
                  ts(a14,2) = ts(a6,VIRT_STEM)
                  ts(a14,3) = ts(a6,VIRT_NOTE)
                  ts(a14,4) = ts(a6,VIRT_STEM)
                end
              end
              if bit(1,ts(a6,STEM_FLAGS)) = UP
                c3 = c2
                c2 = c1
                c1 = c3
              end

              perform get_topbottom (a7,c3,c4)
              if ts(a7,SLUR_X) = 0
                ++a14
                loop for c8 = c3 to c4
                  ts(c8,SLUR_X) = a14
                repeat
                if bit(1,ts(a7,STEM_FLAGS)) = UP
                  ts(a14,1) = ts(a7,VIRT_STEM)
                  ts(a14,2) = ts(a7,VIRT_NOTE)
                  ts(a14,3) = ts(a7,VIRT_STEM)
                  ts(a14,4) = ts(a7,VIRT_NOTE)
                else
                  ts(a14,1) = ts(a7,VIRT_NOTE)
                  ts(a14,2) = ts(a7,VIRT_STEM)
                  ts(a14,3) = ts(a7,VIRT_NOTE)
                  ts(a14,4) = ts(a7,VIRT_STEM)
                end
              end
              if bit(1,ts(a7,STEM_FLAGS)) = UP
                c5 = c4
                c4 = c3
                c3 = c5
              end

        a6 = note we are looking at in first chord
        c1 = head of first chord
        c2 = last note (Y) of first chord

        a7 = note we are looking at in second chord
        c3 = head of second chord
        c4 = last note (Y) of second chord

      If this slur starts or ends on an element which has either (1) a
      staccato dot and/or a legato line, or (2) a spiccato indication
      associated with it, then we need to check to see if this is the
      first time the element in question has been encountered, i.e.,
      element (5) of the slur element ROW is zero.  If so, this parameter
      needs to be adjusted to make space for the indication.  This will
      also shift the position of the slur.



      (1) starting

              c5 = ts(a6,SUBFLAG_2) | ts(a6,ED_SUBFLAG_2)   /* New 05/17/03
                                                            /* At the moment, I am treating
                                                            /* editorial marks the same way
                                                            /* as regular.  In fact, the
                                                            /* addition of square brackets
                                                            /* may require additional
                                                            /* vertical space

              c14 = ts(a6,SLUR_X)        /* index to slur element ROW
              temp = "FGHOadet"          /* note (changed at bottom of loop)
              temp2 = "PQop"             /* stem (changed at bottom of loop)

              loop for c15 = 2 to 0 step -2 /* cases: 2 = start; 0 = end

                if c5 & 0x3c > 0
                  if ts(c14,5) = 0
                    if temp con slurlet     /* if slur starts (ends) on a note
 
              We need to write elements (5) and (6) and to modify elements
              (1) and (3), or elements (2) and (4).
 
                      if mpt < 5            /* this works for both cases
                        stem = UP
                        t3 = 1
                        y = ts(c14,c15+2)
                      else
                        stem = DOWN
                        t3 = -1
                        y = ts(c14,c15+1)
                      end

                      if c5 & 0x38 > 0       /* staccato or legato
                        t2 = notesize
                        y += t2 * t3
               /*  check for interference
                        t4 = 1
                        if stem = DOWN
                          if y >= 0
                            t1 = y / notesize
                            t4 = rem
                          else
                            y = 0 - notesize / 4 + y
                          end
                        else
                          if y <= vpar(8)
                            t1 = y / notesize
                            t4 = rem
                          else
                            y = notesize / 4 + y
                          end
                        end
               /*  adjust for interference with staff
                        if t4 = 0                       /* interference
                          t2 += vpar(1)
                          c16 = t2 + vpar20 / vpar(2)
                          if rem <> 0
                            ++t2
                          end
                          t2 += vpar(1)

                          y = vpar(1) * t3 + y
                          c16 = t3 + 20 * vpar(2) / 2 - vpar20
                          y += c16

                        end
                        c10 = t2
                        if c5 & 0x10 > 0     /* line over dot
                          y = notesize * t3 + y
                          c10 += notesize
                        end
               /*  write elements
                        ts(c14,5) = y
                        if stem = UP
                          ts(c14,2) += c10
                          ts(c14,4) += c10
                          ts(c14,6) = BELOW
                        else
                          ts(c14,1) -= c10
                          ts(c14,3) -= c10
                          ts(c14,6) = ABOVE
                        end
                      end
                      if c5 & 0x04 > 0       /* spiccato
                        if stem = DOWN
                          if y > vpar(1)
                            y = vpar(1)
                          end
                        else
                          if y < vpar(7)
                            y = vpar(7)
                          end
                        end
                        y = 5 * notesize / 4 * t3 + y
                        if stem = UP
                          y += vpar(50)
                        end
               /*  write elements
                        ts(c14,5) = y
                        if stem = UP
                          ts(c14,2) = y
                          ts(c14,4) = y
                          ts(c14,6) = BELOW
                        else
                          ts(c14,1) = y - vpar(50)
                          ts(c14,3) = y - vpar(50)
                          ts(c14,6) = ABOVE
                        end
                      end
                    else
                      if temp2 con slurlet  /* if slur starts (ends) on the stem
 
              We need to write element (5) and (6) and to modify elements
              (1) and (3), or elements (2) and (4).
 
                        if mpt > 2           /* works in both cases
                          stem = UP
                          t3 = -1
                          y = ts(c14,c15+1)
                        else
                          stem = DOWN
                          t3 = 1
                          y = ts(c14,c15+2)
                        end
                        if c5 & 0x38 > 0     /* staccato or legato
                          t2 = vpar(1)
                          y += t2 * t3
                         (y = vpar(1) * t3 + y)
                          c16 = t3 + 20 * vpar(2) / 2 - vpar20
                          y += c16

               /*  check for interference
                          t4 = 1
                          if stem = UP
                            if y >= 0
                              t1 = y / notesize
                              t4 = rem
                            else
                              y = 0 - notesize / 4 + y
                            end
                          else
                            if y <= vpar(8)
                              t1 = y / notesize
                              t4 = rem
                            else
                              y = notesize / 4 + y
                            end
                          end
               /*  adjust for interference with staff
                          if t4 = 0                     /* interference
                            t2 += vpar(1)
                            c16 = t2 + vpar20 / vpar(2)
                            if rem <> 0
                              ++t2
                            end
                            t2 += vpar(1)

                            y = vpar(1) * t3 + y
                            c16 = t3 + 20 * vpar(2) / 2 - vpar20
                            y += c16

                          end
                          c10 = t2
                          if c5 & 0x10 > 0   /* line over dot
                            y = notesize * t3 + y
                            c10 += notesize
                          end
               /*  write elements
                          ts(c14,5) = y
                          if stem = DOWN
                            ts(c14,2) += c10
                            ts(c14,4) += c10
                            ts(c14,6) = ABOVE
                          else
                            ts(c14,1) -= c10
                            ts(c14,3) -= c10
                            ts(c14,6) = BELOW
                          end
                        end
                        if c5 & 0x04 > 0     /* spiccato
                          if stem = DOWN
                            if y < vpar(8)
                              y = vpar(8)
                            end
                          else
                            if y > 0
                              y = 0
                            end
                          end
                          y = vpar(1) * t3 + y
                          c16 = t3 + 20 * vpar(2) / 2 - vpar20
                          y += c16

                          if stem = DOWN
                            y += vpar(50)
                          end
               /*  write elements
                          ts(c14,5) = y
                          if stem = DOWN
                            ts(c14,2) = y
                            ts(c14,4) = y
                            ts(c14,6) = ABOVE
                          else
                            ts(c14,1) = y - vpar(50)
                            ts(c14,3) = y - vpar(50)
                            ts(c14,6) = BELOW
                          end
                        end
                      end
                    end
                  end
                end

      (2) ending

                c5 = ts(a7,SUBFLAG_2) | ts(a7,ED_SUBFLAG_2)   /* New 05/17/03; see above.
                c14 = ts(a7,SLUR_X)            /* index to slur element ROW
                temp = "AFKPdgio"
                temp2 = "OQpt"

              repeat

      Now you can affix the position of the slur, and store the results
      in the appropriate slur element ROWS.  Also, the values of elements
      (1) (2) (3) or (4) can be updated.


                               T H E   P L A N
                            ─────────────────────

      1. Using slurlet and elements (1) to (4), determine tentative start-y
         and end-y values for slur.  Determine orientation (tips up/down)

      2. If c9 = 0, no adjustments are necessary; proceed with placing slur.

      3. Using curve data, convert actual interior y-values to relative
         interior y-values.  If all interior y-values fall below (above) the
         straight line connecting the end points, proceed with placing slur.

      4. Determine interior point with maximum deviation, and raise (lower)
         the slur end-point on that side to the next multiple of vpar(1).
         If there is more than one interior point at the maximum, or if the
         interior point with the maximum is in the center of the slur,
         raise (lower) both slur end-points to the next multiple of vpar(1).

      5. If all interior y-values now fall below (above) straight line
         connecting the end points, proceed with placing slur.

      6. Determine interior point(s) with maximum deviation.  If this point
         (all of these points) fall with the 25%-75% region of the slur,
         increase the curvature one notch, and goto (3); otherwise goto (4).

      To execute this plan, we will need to set up some temporary variables.

         y1  = starting point of slur
         y2  = ending point of slur
         c5  = counting index for interior points
         c6  = index for maximum on left
         c7  = index for maximum on right
         c9  = number of interior points (don't change this)

      I think the easiest way to handle the up/down situation is to convert
      all down values to 1000 * vpar(1) - down, and treat this as part of the
      "up" case.  Initial data includes y1, y2 and the profile data.  When we
      are done, we simply perform the same tranformation to get the final
      y1 and y2 values.




      New feature 05/01/08.  If slur_adjust flag is non-zero, then this
      should turn off all automatic post adjustment of slur posiiton.  I
      think we can do this by setting c9 = 0, which essentially turns off
      the profile.

              if slur_adjust <> 0
                c9 = 0
              end



                            A C T I O N
                           ─────────────

      1. Using slurlet and elements (1) to (4), determine tentative start-y
         and end-y values for slur.  Determine orientation (tips up/down)

              if "ACNRimnq"  con slurlet         /* slur starts on note
                y1 = ts(a6,STAFFLOC)
              else
                if "KLMfgrs"   con slurlet       /* slur starts on Y
                  y1 = ts(a6,OBY)
                else
                  c13 = 3
                  c14 = ts(a6,SLUR_X)
                  c15 = bit(1,ts(a6,STEM_FLAGS))
                  if "FGHOadet"  con slurlet     /* slur starts on H
                    if c15 = UP
                      ++c13
                    end
                  else
                    if c15 = DOWN
                      ++c13
                    end
                  end
                  y1 = ts(c14,c13)
                end
              end
              if "HMNRafnq"  con slurlet         /* slur ends on note
                y2 = ts(a7,STAFFLOC)
              else
                if "CGLemrs"   con slurlet       /* slur ends on Y
                  y2 = ts(a7,OBY)
                else
                  c13 = 1
                  c14 = ts(a7,SLUR_X)
                  c15 = bit(1,ts(a7,STEM_FLAGS))
                  if "AFKPdgio"  con slurlet     /* slur ends on H
                    if c15 = UP
                      ++c13
                    end
                  else
                    if c15 = DOWN
                      ++c13
                    end
                  end
                  y2 = ts(c14,c13)
                end
              end

      2. If c9 = 0, no adjustments are necessary; proceed with placing slur.

              if c9 = 0
                curve = 1
                goto PLACE_SLUR
              end
              c10 = 1000 * vpar(1)
              c10 = 500 * vpar(2)
              if slurlet < chr(96)     /* tips up
                y1 = c10 - y1
                y2 = c10 - y2
                loop for c13 = 1 to c9
                  profile(c13,1) = c10 - profile(c13,2)   /* first cut
                repeat
              else
                y1 += c10
                y2 += c10
                loop for c13 = 1 to c9
                  profile(c13,1) += c10
                repeat
              end

      3. Using curve data, convert actual interior y-values to relative
         interior y-values.  If all interior y-values fall below (above) the
         straight line connecting the end points, proceed with placing slur.
         (see beginning of program for construction of curvedata).

              t1 = 0
              t2 = 0
              curve = 1
              sflag = 1
              if abs(ts(a6,STAFFLOC) - ts(a7,STAFFLOC)) <= vpar(1)
              if abs(ts(a6,STAFFLOC) - ts(a7,STAFFLOC)) <= vpar(1) + 1
                if bit(1,ts(a6,STEM_FLAGS)) = bit(1,ts(a7,STEM_FLAGS))
                  sflag = 0
                end
              end
NEW_CURVE:
              if c9 < 9
                loop for c10 = 1 to c9
                  profile(c10,2) = profile(c10,1) + curvedata(c9,curve,c10)
                repeat
              else
                loop for c10 = 1 to 4
                  profile(c10,2) = profile(c10,1) + curvedata(8,curve,c10)
                repeat
                loop for c10 = 5 to c9 - 4
                  profile(c10,2) = profile(c10,1) + curvedata(8,curve,4) - 1
                repeat
                c11 = 1
                loop for c10 = c9 to c9 - 4 step -1
                  profile(c10,2) = profile(c10,1) + curvedata(8,curve,c11)
                  ++c11
                repeat
              end

              r1 = flt(y1) + .5 - flt(vpar(2))
              r2 = flt(y2 - y1)
              r3 = flt(c9+1)
              r2 = r2 / r3
              c14 = 0
              c15 = 0
              c12 = c9 + 1 >> 1
              c13 = c9 >> 1 + 1
              t5 = 0
              t6 = 0
              loop for c5 = 1 to c9
                r1 += r2
                c11 = fix(r1)
                c11 -= profile(c5,2)
                if c11 > 0
                  if c5 <= c12
                    if c11 > c14
                      c14 = c11
                      t5 = c5
                    end
                  end
                  if c5 >= c13
                    if c11 > c15
                      c15 = c11
                      t6 = c5
                    end
                  end
                end
              repeat
              if c14 = 0 and c15 = 0
                goto FIX_ENDS
              end

      4. Determine interior point with maximum deviation, and raise (lower)
         the slur end-point on that side to the next multiple of vpar(1).
         If there is more than one interior point at the maximum, or if the
         interior point with the maximum is in the center of the slur,
         raise both slur end-points to the next multiple of vpar(1).


              c7 = 0
              if c9 > 4 and bit(0,c9) = 0                                 /*
                c6 = c9 >> 1                                              /*   
                if t5 = c6 or t6 - 1 = c6                                 /*     TRIAL
                  c7 = 1                                                  /*   
                  if bit(1,ts(a6,STEM_FLAGS)) <> bit(1,ts(a7,STEM_FLAGS)) /*
                    if abs(ts(a6,STAFFLOC) - ts(a7,STAFFLOC)) <= vpar(10) /*
                      if curve = 1                                        /*
                        if c15 > c14                                      /*
                          t1 = 2                                          /*
                        else                                              /*   
                          t2 = 2                                          /*   
                        end                                               /*     TRIAL
                        c7 = 0                                            /*   
                      end                                                 /*
                    end                                                   /*
                  end                                                     /*
                end
              end
NEW_HEIGHT:
              if c15 = c14 or sflag = 0 or c7 = 1
                y2 /= vpar(1)
                --y2
                y2 *= vpar(1)  /*  raise the end
                y1 /= vpar(1)
                --y1
                y1 *= vpar(1)  /*  raise the start
                y2 -= vpar(1)
                c16 = y2 * 2 / vpar(2)
                y2 -= rem
                y1 -= vpar(1)
                c16 = y1 * 2 / vpar(2)
                y1 -= rem

                if sflag = 0
                  sflag = 1
                end
              else
JKL:
                if c15 > c14
                  if t2 > 0
                    t1 = 0
                    t2 = 0
                  end
                  if t1 = 2
                    t1 = 0
                    c14 = c15 + 1
                  else
                    ++t1
                    y2 /= vpar(1)
                    --y2
                    y2 *= vpar(1)  /*  raise the end
                    y2 -= vpar(1)
                    c16 = y2 * 2 / vpar(2)
                    y2 -= rem

                  end
                end
                if c14 > c15
                  if t1 > 0
                    t1 = 0
                    t2 = 0
                  end
                  if t2 = 2
                    t2 = 0
                    c15 = c14 + 1
                    goto JKL
                  else
                    y1 /= vpar(1)
                    --y1
                    y1 *= vpar(1)  /*  raise the start
                    y1 -= vpar(1)
                    c16 = y1 * 2 / vpar(2)
                    y1 -= rem

                  end
                end
              end

      5. If all interior y-values now fall below (above) straight line
         connecting the end points, proceed with placing slur.

              r1 = flt(y1) + .5 - flt(vpar(2))
              r2 = flt(y2 - y1)
              r3 = flt(c9+1)
              r2 = r2 / r3
              c14 = 0
              c15 = 0
              c6 = 0
              c7 = 0
              c12 = c9 + 1 >> 1
              c13 = c9 >> 1 + 1
              loop for c5 = 1 to c9
                r1 += r2
                c11 = fix(r1)
                c11 -= profile(c5,2)
                if c11 > 0
                  if c5 <= c12
                    if c11 > c14
                      c6 = c5
                      c14 = c11
                    end
                  end
                  if c5 >= c13
                    if c11 > c15
                      c7 = c5
                      c15 = c11
                    end
                  end
                end
              repeat
              if c6 = 0 and c7 = 0
                goto FIX_ENDS
              end
              t5 = c6
              t6 = c7

      6. Determine interior point(s) with maximum deviation.  If this point
         (all of these points) fall with the 25%-75% region of the slur,
         increase the curvature one notch, and goto (3); otherwise goto (4).

              c5 = 10000 / (c9 + 1)
              c6 *= c5
              c7 *= c5
              if c14 >= c15 and c6 >= 2500 and curve < 4
                ++curve
                goto NEW_CURVE
              end
              if c14 <= c15 and c7 <= 7500 and curve < 4
                ++curve
                goto NEW_CURVE
              end
              goto NEW_HEIGHT

      Transform to actual y-values

FIX_ENDS:
              c10 = 1000 * vpar(1)
              c10 = 500 * vpar(2)
              if slurlet < chr(96)     /* tips up
                y1 = c10 - y1
                y2 = c10 - y2
              else
                y1 -= c10
                y2 -= c10
              end

           Adjust slur height if both ends show tuplet

              if bit(4,ts(a6,SUPER_FLAG)) = 1 and bit(5,ts(a7,SUPER_FLAG)) = 1
                c10 = 0   /* = no
                goto ADJS(tpflag+1)
ADJS(1):
                if ts(a6,BEAM_FLAG) > 0 and ts(a7,BEAM_FLAG) > 0
                  if ts(a7,MULTI_TRACK) = 0
                    c10 = 1
                  end
                else
                  c10 = 1
                end
                goto ADJSE
ADJS(2):                       /* always
                c10 = 1
                goto ADJSE
ADJS(3):                       /* never
                goto ADJSE
ADJS(4):                       /* only when tips down
                if slurlet > chr(96)     /* tips down
                  c10 = 1
                end
                goto ADJSE
ADJS(5):                       /* only when tips up
                if slurlet < chr(96)     /* tips up
                  c10 = 1
                end
ADJSE:

                if c10 = 1
                  if slurlet < chr(96)     /* tips up
                    if y1 + y2 > vpar(6) << 1
                      y1 += vpar(2)
                      y2 += vpar(2)
                    end
                  else
                    if y1 + y2 < vpar(4)
                      y1 -= vpar(2)
                      y2 -= vpar(2)
                    end
                  end
                end
              end


      For both starting and ending chords, (1) find next empty slot in
      in each SLUR_X row and construct the following information:

        first element
        ────────────────────
           bit 27:     start/end flag (0 = start, 1 = end)
           bits 24-26: slur number - 1 (0 to 7)
           bits 17-23: curvature information (end only)
           bit 16:     up/down flag (0 = tips up, 1 = tips down) (end only)
           bits 0-15:  x-offset + 1000 (always a positive number)
        second element
        ─────────────────────
           y position relative to the staff
        third element (05/06/03)
        ─────────────────────
           print suggestion for this end of the slur

PLACE_SLUR:

          Starting point

              c10 = 1000           /* x-offset
              if "ACRNimnq" con slurlet     /* start on "n"
                if ts(a6,LOCAL_XOFF) > 0
                  c10 += ts(a6,LOCAL_XOFF)
                end
                if mpt > 3
                  c10 += hpar(82) * 3 / 4
                end
              else
                if "KLMfgrs" con slurlet    /* start on "Y"
                  if bit(1,ts(a6,STEM_FLAGS)) = UP
                    if ts(c2,LOCAL_XOFF) > 0
                      c10 += ts(a6,LOCAL_XOFF)
                    end
                    if mpt > 3
                      c10 += hpar(82) * 3 / 4
                    end
                  end
                else
                  if "PQop" con slurlet     /* start on "s"
                    if mpt < 3
                      c10 -= hpar(82) / 3
                    else
                      c10 += hpar(82) / 3
                    end
                  end
                end
              end
              c11 = sgroup(a4,3) << 24       /* slur number
              c11 += c10                     /* odd numbered element
              c12 = ts(a6,SLUR_X)
              loop for c13 = 7 to 31 step 2
              loop for c13 = 7 to (TS_SIZE - 2) step 3       /* 05/06/03
                if ts(c12,c13) = 0
                  goto PLACE_SLUR1
                end
              repeat
PLACE_SLUR1:
              ts(c12,c13) = c11
              ++c13
              ts(c12,c13) = y1

           Fine tuning for special situation

              if slurlet = "i"
                if ts(a6,STAFFLOC) - ts(a7,STAFFLOC) >= 0
                  c17 = ts(a7,SUBFLAG_2) | ts(a7,ED_SUBFLAG_2)   /* New 05/17/03
                  if c17 & 0x3c > 0                              /* New
                    ts(c12,c13) -= vpar(2)
                  end
                end
              end

           Code added 05/06/03 get print suggestion for this end of slur

              ++c13
              c11 = sgroup(a4,3)                   /* 0 to 7
              if c11 > 3
                c11 -= 4                           /* 0 to 3 = (,[,{,z
              end
              c11 *= 4                             /* 0,4,8,12
              c11 += 81                            /* 81,85,89,93  (97,101,105,109)
              c10 = ts(a6,TSR_POINT)
              ts(c12,c13) = ors(tsr(c10){c11,4})

           End code addition


         05-27-94
         Somehow, I can't figure out why this code was written this way
         It seems that tips up would automatically imply that the slur
         was under the object, and tips down would imply that the slur
         was over the object.  The revised code reflects this thought
         (which may very well be naive).

              if "PQadet" con slurlet        /* starting from over (3)
                ts(c12,3) = y1  /*?   - vpar(1)
              end
              if "FGHOop" con slurlet        /* starting from under (4)
                ts(c12,4) = y1  /*?   + vpar(1)
              end

              if "opadet" con slurlet        /* starting from over (3)
                ts(c12,3) = y1 - vpar(1)     /* new value
                ts(c12,3) = y1 - vpar(1)
                c16 = ts(c12,3) * 2 / vpar(2)
                ts(c12,3) -= rem

              end
              if "FGHOPQ" con slurlet        /* starting from under (4)
                ts(c12,4) = y1 + vpar(1)     /* new value
                ts(c12,4) = y1
                c16 = ts(c12,4) * 2 / vpar(2)
                if rem <> 0
                  ++ts(c12,4)
                end
                ts(c12,4) += vpar(1)
              end

          Ending point

              c10 = 1000           /* x-offset
              if "HMNRnafq" con slurlet     /* end on "n"
                if ts(a7,LOCAL_XOFF) < 0
                  c10 += ts(a6,LOCAL_XOFF)
                end
                if mpt < 6
                  c10 -= hpar(82) * 3 / 4
                end
              else
                if "CGLrems" con slurlet    /* end on "Y"
                  if bit(1,ts(a7,STEM_FLAGS)) = DOWN
                    if ts(c4,LOCAL_XOFF) < 0
                      c10 += ts(a6,LOCAL_XOFF)
                    end
                    if mpt < 5
                      c10 -= hpar(82) * 3 / 4
                    end
                  end
                else
                  if "OQpt" con slurlet     /* end on "s"
                    if mpt < 3
                      c10 -= hpar(82) / 3
                    else
                      c10 += hpar(82) / 3
                    end
                  end
                end
              end
              c11 = sgroup(a4,3)             /* slur number
              c11 += 16                      /* end flag
              c11 <<= 8
              c11 += curve << 1              /* curvature
              if slurlet > chr(96)     /* tips up
                ++c11                        /* tips up/down flag
              end
              c11 <<= 16
              c11 += c10                     /* x-offset
              c12 = ts(a7,SLUR_X)
              loop for c13 = 7 to 31 step 2
              loop for c13 = 7 to (TS_SIZE - 2) step 3       /* 05/06/03
                if ts(c12,c13) = 0
                  goto PLACE_SLUR2
                end
              repeat
PLACE_SLUR2:
              ts(c12,c13) = c11
              ++c13
              ts(c12,c13) = y2

           Code added 05/06/03 get print suggestion for this end of slur

              ++c13
              c11 = sgroup(a4,3)                   /* 0 to 7
              if c11 > 3
                c11 -= 4                           /* 0 to 3 = (,[,{,z
              end
              c11 *= 4                             /* 0,4,8,12
              c11 += 97                            /* 97,101,105,109
              c10 = ts(a7,TSR_POINT)
              ts(c12,c13) = ors(tsr(c10){c11,4})

           End code addition


         05-27-94
         See above.  I don't understand how this code got written
         as it did.  It seems self evident that the over-under
         question is decided entirely by the direction of the
         slur tips.

              if "OQdgio" con slurlet        /* ending from over (1)
                ts(c12,1) = y2   /*? - vpar(1)
              end
              if "AFKPpt" con slurlet        /* ending from under (2)
                ts(c12,2) = y2   /*  + vpar(1)
              end



              if "ptdgio" con slurlet        /* ending from over (1)
                ts(c12,1) = y2 - vpar(1)     /* new value
                ts(c12,1) = y2 - vpar(1)
                c16 = ts(c12,1) * 2 / vpar(2)
                ts(c12,1) -= rem

              end
              if "AFKPOQ" con slurlet        /* ending from under (2)
                ts(c12,2) = y2 + vpar(1)     /* new value
                ts(c12,2) = y2
                c16 = ts(c12,2) * 2 / vpar(2)
                if rem <> 0
                  ++ts(c12,2)
                end
                ts(c12,2) += vpar(1)

              end


            repeat

      ╔═══════════════════════════════════════════════════════╗
      ║   This is the end of the loop which processes slurs   ║
      ╚═══════════════════════════════════════════════════════╝

          end
YYYY:
        repeat
        maxsct = a14

 *****************************************************************
     Processing loop (loop ends at ZZZ)   PROCESSING TS ARRAY

     Actions:

        I. Construct text sub-object, if present

       II. Deal with music

           A. Bar Lines

           B. Clef changes, Time changes

           C. Signs, Words, Marks

           D. Figures

           E. Notes/Rests

               1. Accidentals
               2. Note heads, dots
               3. Leger lines
               4. Stems and beams

      III. Write object records into intermediate file

        p += firstsp
        loop for a1 = 1 to sct
          nodtype = ts(a1,TYPE)
          a5 = ts(a1,TEXT_INDEX)
          if a5 > 0
            ttext = tsdata(a5) // pad(1)
          else
            ttext = pad(1)
          end
          sobcnt = 0
          obx = p
          if nodtype = DIV_CHG
            goto ZZZ
          end

     Get the spn (spacing) parameter

          spn = ts(a1,SPN_NUM)


     I am moving this code to the point where notes are really typeset.
     The problem with having it here is that if there are chords with
     text, or if there are cue-notes simultaneous with the text, then
     the text may not get set.

     I. Construct Text Sub-Object


          if nodtype = NOTE
            if ttext{1} in ['A'..'Z','a'..'z','!'..'(','\','=']
              c5 = mtfont
              perform spacepar
              temp2 = ttext
              if temp2 con "$$$$"
                ttext = temp2{1,mpt-1}
                a4 = int(temp2{mpt+4..})        /* x offset (calculated earlier)
              else
                putc Program Error at 10052
              end
              temp2 = ttext // "| "
              ttextcnt = 0
CCCD:
              if temp2 con "|"
                ttext = temp2{1,mpt-1}
                temp2 = temp2{mpt+1..}
                ++ttextcnt
                ttextarr(ttextcnt) = trm(ttext)
                goto CCCD
              end
              loop for a7 = 1 to ttextcnt

                ttext = ttextarr(a7)
 
   determine values of xbytearr
 
                a6 = len(ttext)
                xbytearr(a7) = "* "
                if "-_" con ttext{a6}
                  ttext = ttext{1,a6-1}
                  xbytearr(a7) = "-_"{mpt} // " "
                  if mpt = 2
                    a6 = len(ttext)
                    if ",.;:!?" con ttext{a6}
                      ttext = ttext{1,a6-1}
                      xbytearr(a7) = ",.;:!?"{mpt} // " "
                    end
                  end
                end
                ttextarr(a7) = ttext
              repeat
 
    determine length of ttext
 
              a5 = 0
              loop for a7 = 1 to ttextcnt
                c5 = 0
                ttext = ttextarr(a7)
                loop for c4 = 1 to len(ttext)
*   adjust for backslash (\) sequence
                  if ttext{c4} = "\"
                    a6 = ors(ttext{c4+2})
                    if ttext{c4+1} = "0"
                      a6 += 128
                    end
                    c4 += 2
                  else
                    a6 = ors(ttext{c4})
                  end
                  c5 += spc(a6)
                repeat
                if c5 > a5
                  a5 = c5
                end
              repeat
 
    determine relative position of ttext
 
              x = p - a4
              sobx = x - obx
              loop for a8 = 1 to ttextcnt
                ttext = ttextarr(a8)
                ++sobcnt
                temp3 = "T " // chs(sobx) // " " // chs(a8) // " "
                if ttext con "="
                  ttext{mpt} = "-"
                end
                temp3 = temp3 // ttext // " "
                sobl(sobcnt) = temp3 // xbytearr(a8) // chs(a5)
              repeat
            end
          end


    II. Typeset Music

      A. Typeset Bar Line

          if nodtype = BAR_LINE

       Zero out the rest_flag(s)    03/18/06

            loop for a2 = 1 to MAX_PASS
              rest_flag(a2) = 0
            repeat

            a2 = hpar(36)
            a14 = ts(a1,BAR_TYPE)

     determine location of obx for this object

            if bit(1,ts(a1,REPEAT)) = 1    /* backward repeat
              a2 += hpar(43)
            end
            a10 = hpar(43) + hpar(93) - hpar(80)

   Old Version                                                           shift for
                                                                        forward dots(repeats)
    a14   a2+ (add to p)       a4 (1st shft) a5 (2nd shft)  a8 (inc)        a10
   ----  ----                 ----           ---------     ----            -----
     1    0                    0             0               0              a10
     2    hpar(79)            -hpar(79)      0               0              a10
     3    0                    0             0               0              a10
     5    hpar(44)            -a2            0               0              a10
     6    hpar(81) + hpar(79) -a2           -hpar(79)        0              a10
     9    0                    0            +hpar(45)        hpar(45)   a10 + hpar(45)
    10    hpar(45)            -hpar(45)      0               hpar(79) hpar(43)+hpar(96)-hpar(80)



      hpar(44) = actual white space between two light lines
      hpar(45) = actual white space between heavy/light, light/heavy and heavy/heavy combinations
      hpar(79) = thickness of light line
      hpar(81) = thickness of heavy line

                                                                         shift for
                                                                        forward dots(repeats)
    a14   a2+ (add to p)       a4 (1st shft) a5 (2nd shft)  a8 (inc)        a10
   ----  ----                 ----           ---------     ----            -----
     1    0                    0             0               0              a10
     2  { hpar(81) - hpar(79  a2             0               0              a10
               + 1 }
     3    0                    0             0               0              a10
     5    hpar(44) + hpar(79) a2             0               0              a10
     6  { hpar(45) + hpar(81) a2   - { hpar(81) - hpar(79)   0              a10
               + 1 }                          + 1 }
     9    0                    0       hpar(81) + hpar(45)   a5           a10 + a5
    10    hpar(81) + hpar(45) a2             0         { hpar(81) -   hpar(43)+hpar(96)-hpar(80)
                                                      hpar(79) + 1 }


            a4 = 0
            a5 = 0
            a8 = 0
            if a14 = HEAVY
              a2 += hpar(81) - hpar(79) + 1
              a4 = hpar(81) - hpar(79) + 1
            end
            if a14 = DOUBLE_REG or a14 = DOUBLE_DOTTED
              a2 += hpar(44) + hpar(79)
              a4 = hpar(44) + hpar(79)
            end
            if a14 = REG_HEAVY
              a2 += hpar(45) + hpar(81) + 1
              a4 = hpar(45) + hpar(81) + 1
              a5 = 0 - (hpar(81) - hpar(79) + 1)
            end
            if a14 = HEAVY_REG
              a5 = hpar(81) + hpar(45)
              a8 = a5
              a10 += a5
            end
            if a14 = DOUBLE_HEAVY
              a2 += hpar(81) + hpar(45)
              a4 =  hpar(81) + hpar(45)
              a8 =  hpar(81) - hpar(79) + 1
              a10 = hpar(43) + hpar(96) - hpar(80)
            end
            obx = p + a2
            if ts(a1,NODE_SHIFT) > 0
              putc node_shift for barline = ~ts(a1,NODE_SHIFT)
              obx += ts(a1,NODE_SHIFT)
            end

*
*    put out signet signs (if present)
*
            if bit(1,ts(a1,BAR_FLAGS)) = 1     /* segno sign
              out = "0"
              jtype = "D"
              jcode = 8 + sigflag
              pcode = 106                 /* music font
              oby = vpar(45)
              if nstaves = 2
                oby += 1000
              end
              putobjpar = 0
              jscrdat = ""
              perform putobj
              jcode = 5 - sigflag
              oby = 0 - vpar(43)
              jscrdat = ""
              perform putobj
              if sigflag = 0
                sigflag = 1
              end
            end
*
*    put out fermata signs (if present)
*
            if ts(a1,BAR_FLAGS) & 0x000c > 0
              putobjpar = 0
              if bit(2,ts(a1,BAR_FLAGS)) = 1     /* fermata over bar
                out = "0"
                jtype = "D"
                jcode = 5
                pcode = 101                 /* music font
                oby = 0 - vpar(3)
                obx -= vpar(2)
                jscrdat = ""
                perform putobj
                obx += vpar(2)
              end
              if bit(3,ts(a1,BAR_FLAGS)) = 1     /* fermata under bar
                out = "0"
                jtype = "D"
                jcode = 9
                pcode = 102                 /* music font
                oby = vpar(3) + vpar(8)
                if nstaves = 2
                  oby += 1000
                end
                obx -= vpar(2)
                jscrdat = ""
                perform putobj
                obx += vpar(2)
              end
            end
            oby = 0

     contruct superobject string for bar line

            supcnt = 0
*    look for termination of ending
            a9 = ts(a1,BACK_ENDING)
            if a9 <> 0
              if esnum > 0
                ++supcnt
                supnums(supcnt) = esnum
                a6 = esnum
              else
                return 4
              end
              esnum = 0
            end
*    look for termination of long trill ~~~~
            if bit(0,ts(a1,BAR_FLAGS)) = 0
              loop for a3 = 1 to MAX_PASS
                if tsnum(a3) > 0
                  ++supcnt                         /* stop trill
                  supnums(supcnt) = tsnum(a3)
                end
              repeat
            end
*    look for origination of ending
            if ts(a1,FORW_ENDING) > 0
              ++snum
              esnum = snum
              ++supcnt
              supnums(supcnt) = esnum
            end
*    construct supernumber string for object
            out = chs(supcnt)
            loop for a3 = 1 to supcnt
              out = out // " " // chs(supnums(a3))
            repeat
            supcnt = 0

     Typeset elements of the bar line

*    numbered measure                   /* Code added 02-23-97
            a3 = ts(a1,M_NUMBER)
            if a3 > 0
              c5 = 38
              perform spacepar
              c5 = spc(176) >> 1        /* space for small "0"
              if a3 > 9
                c5 <<= 1
              end
              sobl(1) = "W " // "-" // chs(c5) // " 0 38 "
              sobcnt = 1
              if a3 > 9
                c5 = a3 / 10
                a3 = rem
                sobl(1) = sobl(1) // "\0" // chs(c5)
              end
              sobl(1) = sobl(1) // "\0" // chs(a3)
            end

*    back-repeat
            if bit(1,ts(a1,REPEAT)) = 1   /* backward repeat
              x = p + hpar(36)
              x += ts(a1,NODE_SHIFT)     /* This line added 09/22/03 (but not fully checked)
              y = vpar(3)
              z = 44                      /* music font
              kscrdat = ""
              perform subj
              y = vpar(5)
              perform subj
            end
*    first of double bar
            y = 0
            if a14 > 3
              a3 = a14 & 0x0c
              z = a3 / 2 + 80             /* music font
              x = obx - a4
              kscrdat = ""
              perform subj
            end
*    second or single bar
            a3 = ts(a1,BAR_TYPE) & 0x03
            z = a3 * 2 + 80               /* music font
            x = obx + a5
            kscrdat = ""
            perform subj
*    forward-repeat
            if bit(0,ts(a1,REPEAT)) = 1   /* forward repeat
              x = obx + a10
              a8 += hpar(43)
              y = vpar(3)
              z = 44                      /* music font
              kscrdat = ""
              perform subj
              y = vpar(5)
              perform subj
            end
*    put out object (and sub-objects)
            jtype = "B"
            jcode = ts(a1,BAR_NUMBER)
            if sobcnt = 1
              pcode = z                   /* music font
            else
              pcode = sobcnt
            end
            oby = ts(a1,NUM_STAVES) - 1 * 1000 + a14
            putobjpar = 0
            jscrdat = tsdata(ts(a1,TEXT_INDEX))

         Strip the operative barnum from the front of jscrdat

            opbarnum = int(jscrdat)
            if jscrdat con "+"
              jscrdat = jscrdat{mpt+1..}
            end

            perform putobj


*    put out ending super-object
            if a9 <> 0                    /* backward ending
              if ts(a1,FORW_ENDING) > 0
                out = "-" // chs(hpar(41))
              else
                out = "0"
              end
              out = out // " -" // chs(vpar(40)) // " "
              out = out // " -" // chs(ending_height) // " "      /* changed 01/06/06
              out = out // chs(vpar(41)) // " "
              if a9 > 0                   /* ending stops
                out = out // chs(vpar(41))
              else                        /* ending discontinues
                a9 = 0 - a9
                out = out // "0"
              end
              ++outpnt
              tput [Y,outpnt] H ~a6  E ~a9  0 ~out
            end
*    put out long trill super-object
            if bit(0,ts(a1,BAR_FLAGS)) = 0
              loop for c5 = 1 to MAX_PASS
                if tsnum(c5) > 0
                  out = "H " // chs(tsnum(c5)) // " R " // chs(ctrarrf(c5))
                  out = out // " 0"
                  ++outpnt
                  tput [Y,outpnt] ~out  -~hpar(42)  ~try(c5)
                  tsnum(c5) = 0
                  ctrarrf(c5) = 0
                end
              repeat
            end
*    adjust p
            p = obx + ts(a1,SPACING) + a8

            goto ZZZ
          end

      B. Typeset Clef change, Time change, Key change

          if nodtype = CLEF_CHG

     Code added 01/17/04 to deal with time clef in measure groups

            if ts(a1,DOLLAR_SPN) = 6913             /* 6913 used here as a code, not a value
              spn = 6913
            end                                     /* otherwise don't change spn

            a3 = ts(a1,STAFF_NUM) + 1         /* staff number

            if ts(a1,NODE_SHIFT) < 0
              a7 = 0 - ts(a1,NODE_SHIFT)
              putc backing up clef sign by amount = ~a7
              p += ts(a1,NODE_SHIFT)
            end

            obx = p

            clef(a3) = ts(a1,CLEF_NUM)
            z = ts(a1,CLEF_FONT)              /* music font
            k = ts(a1,TRANS_FLAG)
            oby = ts(a1,STAFF_NUM) * 1000     /* added 5-28-93
            oby += ts(a1,CLEF_STAFF_POS)
            perform putclef (a3)
            p += ts(a1,SPACING)

            goto ZZZ
          end
*
          if nodtype = DESIGNATION

     Code added 01/17/04 to deal with designation in measure groups

            if ts(a1,DOLLAR_SPN) = 6913             /* 6913 used here as a code, not a value
              spn = 6913
            end                                     /* otherwise don't change spn

            c5 = 37
            perform spacepar

        Introducing optional conversion to ligitures in designations  04/22/04

            if ligit_flag = 1
              if len(ttext) > 1 and ttext{1,2} = "ff"
                ttext{1,2} = "f\@f"
              end
LIGCON3:
              if ttext con "ffi"
                ttext{mpt,3} = "\0:"
                goto LIGCON3
              end
              if ttext con "ffl"
                ttext{mpt,3} = "\0;"
                goto LIGCON3
              end
              if ttext con "ff"
                ttext{mpt,2} = "\0<"
                goto LIGCON3
              end
              if ttext con "fi"
                ttext{mpt,2} = "\0="
                goto LIGCON3
              end
              if ttext con "fl"
                ttext{mpt,2} = "\0>"
                goto LIGCON3
              end
            end
#if AUTOSCR
#else
            perform kernttext                  /* New 04/22/04
#endif
            jtype = "D"
            jcode = 5
            obx = p
            oby = ts(a1,STAFF_NUM) * 1000     /* added 5-28-93
            oby -= tword_height * vpar(1)
            out = "0"
            sobl(1) = ""
            temp3 = "W 0 0 37 " // ttext
            temp3 = "W 0 0 " // chs(dtivfont) // " " // ttext
            pcode = 1
            putobjpar = 0
            jscrdat = ""
            perform putobj
            goto ZZZ
          end
*
          if nodtype = METER_CHG

     Code added 01/17/04 to deal with meter changes in measure groups

            if ts(a1,DOLLAR_SPN) = 6913             /* 6913 used here as a code, not a value
              spn = 6913
            end                                     /* otherwise don't change spn

            tnum = ts(a1,TIME_NUM) / 100
            tden = rem
            oby = 0
            k = p
            loop for h = 1 to ts(a1,NUM_STAVES)
              p = k
              perform settime (a3)
              oby += 1000
            repeat
            if tnum = 1 and tden = 1
              tnum = 4
              tden = 4
            end
            if tnum = 0 and tden = 0
              tnum = abflg
              tden = 2
            end
            goto ZZZ
          end
*
          if nodtype = AX_CHG

     Code added 01/17/04 to deal with key changes in measure groups

            if ts(a1,DOLLAR_SPN) = 6913             /* 6913 used here as a code, not a value
              spn = 6913
            end                                     /* otherwise don't change spn

            h = ts(a1,3)                               /* new key
            k = ts(a1,4)                               /* old key
            a3 = ts(a1,NUM_STAVES)                     /* number of staves
            a4 = 0
            a5 = 0                                     /* added 08/23/06
            perform key_change (h, k, a3, a4, a5)      /* emptyspace(.,.) not set
            key = h                                /* 08/23/06 5th variable added to procedure

     NOTE: The following instruction was added 05/29/05 to fix a minor bug
           that I have never seen before.  It makes perfect sense that we
           should go to the next element in the ts(.) array, and I can't see
           how this "bug" has remained hidden for so long.  My worry is that
           there was a good reason why we wanted to "fall through" to the
           note processing section, although this would be very poor programming
           practice.  I do believe, however, in light of the fact that this
           program has worked properly for so long, that we need to keep an
           eye on this situation.  This "goto" instruction is a major change!

            goto ZZZ
          end

      C. Typeset Signs, Words and Marks which are Objects

          if nodtype = SIGN or nodtype = WORDS or nodtype = MARK
            putobjpar = 0
*           obx = p
            a4 = ts(a1,TEXT_INDEX)
            ttext = tsdata(a4)
            ttext = trm(ttext)
            out = "0"

      determine vertical positions of object and superobject

            if ts(a1,SIGN_TYPE) = SEGNO
              oby = 0 - vpar(43)
            else
              if ts(a1,SIGN_POS) = ABOVE
                oby = 0 - vpar(44)
              else
                oby = vpar(45)
              end
            end
            oby1 = oby
            oby2 = oby
            obx1 = obx
            obx2 = obx

      Comment: 01/07/06 The code here is somewhat convoluted, but I think
          this addition corrects a problem with the way print suggestions
          interact with transpositions.  Stay alert!

            if nodtype = MARK
              oby = 0
            end

            if ts(a1,POSI_SHIFT1) > 0
              a3 = ts(a1,POSI_SHIFT1) & 0xff
              if a3 > 0
                oby1 = a3 - 0x80 * vpar(2) / 10
                yposi_shift = 0
              else
                a3 = ts(a1,POSI_SHIFT1) >> 8
                yposi_shift = a3 & 0xff
                if yposi_shift > 0
                  yposi_shift = yposi_shift - 0x80 * vpar(2) / 10
                end
              end
              xposi_shift = ts(a1,POSI_SHIFT1) >> 16
              if xposi_shift > 0
                xposi_shift = xposi_shift - 0x80 * vpar(2) / 10
              end
            else
              yposi_shift = 0
              xposi_shift = 0
            end
            save_xposi_shift = xposi_shift
            obx1 += xposi_shift
            oby1 += yposi_shift

            if ts(a1,POSI_SHIFT2) > 0
              a3 = ts(a1,POSI_SHIFT2) & 0xff
              if a3 > 0
                oby2 = a3 - 0x80 * vpar(2) / 10
                yposi_shift = 0
              else
                a3 = ts(a1,POSI_SHIFT2) >> 8
                yposi_shift = a3 & 0xff
                if yposi_shift > 0
                  yposi_shift = yposi_shift - 0x80 * vpar(2) / 10
                end
              end
              xposi_shift = ts(a1,POSI_SHIFT2) >> 16
              if xposi_shift > 0
                xposi_shift = xposi_shift - 0x80 * vpar(2) / 10
              end
            else
              yposi_shift = 0
              xposi_shift = 0
            end
            obx2 = xposi_shift
            oby2 += yposi_shift

            temp = " " // chs(oby1)
            temp2 = " " // chs(oby2)

            a2 = ts(a1,SUPER_TYPE)
*     construct superflags for object
            if a2 > 0
              a3 = a2 + 1 / 2
              a8 = 0
              if a3 = 4
                a8 = 1
                a3 = 3
              end
              if rem = 0     /* start of super-object

                a4 = a3 - WEDGES * 5 + ts(a1,S_TRACK_NUM) /* row element
                loop for a5 = 1 to 5
                  if smusdir(a4,1) = 0                    /* must be zero to use
                    a5 = 1000
                  else                                    /* else look at others
                    ++a4
                    if a4 > a3 * 5
                      a4 -= 5                             /* in the set
                    end
                  end
                repeat
                if a5 <> 1000
                  putc Too many active ...
                  if a3 = WEDGES
                    putc wedges.
                  else
                    if a3 = DASHES
                      putc sets of dashes.
                    else
                      putc transpositions of one type.
                    end
                  end
                  putc Typesetting halted
                  stop
                end
                ++snum
                smusdir(a4,1) = snum
                smusdir(a4,4) = oby2
                if a3 = WEDGES
                  smusdir(a4,2) = ts(a1,WEDGE_SPREAD)
                  smusdir(a4,3) = ts(a1,WEDGE_OFFSET) + obx2
                else
                  if a3 = DASHES
                    if ts(a1,FONT_NUM) = 0
                      c5 = mtfont
                    else
                      c5 = ts(a1,FONT_NUM)
                    end
                    smusdir(a4,3) = c5
                    perform wordspace
                    smusdir(a4,2) = a5 + obx2
                  else
                    smusdir(a4,3) = obx2
                    smusdir(a4,4) -= oby    /* tricky code
                    if a3 = OCT_UP
                      smusdir(a4,2) = 0
                    end
                    if a3 = OCT_DOWN
                      smusdir(a4,2) = 1
                    end
                    if a3 = DBL_OCT_UP
                      smusdir(a4,2) = 2
                    end
                    if a3 = DBL_OCT_DOWN
                      smusdir(a4,2) = 3
                    end
                  end
                end

              else                 /* end of super-object

                a4 = a3 - WEDGES * 5 + ts(a1,S_TRACK_NUM) /* row element
                loop for a5 = 1 to 5
                  if smusdir(a4,1) <> 0                   /* must be non zero to use
                    a5 = 1000
                  else                                    /* else look at others
                    ++a4
                    if a4 > a3 * 5
                      a4 -= 5                             /* in the set
                    end
                  end
                repeat
                if a5 <> 1000
                  putc Attempt to end a ...
                  if a3 = WEDGES
                    putc wedge ...
                  else
                    if a3 = DASHES
                      putc set of dashes ...
                    else
                      putc transposition of a type ...
                    end
                  end
                  putc that wasn't properly started.
                  putc Typesetting halted
                  stop
                end
                save_a4 = a4
              end
              out = "1 " // chs(smusdir(a4,1))
            end

      if single character, write object

            a3 = ts(a1,SIGN_TYPE)
            if a3 = PED or a3 = END_PED
              pcode = 112 + a3           /* music font
              jtype = "S"
              jcode = 0
              obx = obx1
              oby = ts(a1,STAFF_NUM) * 1000 + oby1
              if ts(a1,ISOLATED) = 1
                jtype = "I"
              end
              jscrdat = ""
              perform putobj
              goto VT2
            end
            if a3 = LETTER_DYNAM          /* one letter dynamics
              if ttext con "Z"
#if SFZ
                ttext{mpt,1} = "sfz"
#else
                ttext{mpt,1} = "sf"
#endif
              end
              if len(ttext) = 1 and "pf" con ttext
                if mpt = 1
                  pcode = 108             /* music font
                else
                  pcode = 110             /* music font
                end
                jtype = "S"
                jcode = 0
                obx = obx1
                oby = ts(a1,STAFF_NUM) * 1000 + oby1
                if ts(a1,ISOLATED) = 1
                  jtype = "I"
                end
                jscrdat = ""
                perform putobj
                goto VT2
              end
            end

     put out segno signs (as directives)

            if a3 = SEGNO
              pcode = 106                 /* music font
              jtype = "D"
              jcode = 8 + sigflag
              obx = obx1
              oby = ts(a1,STAFF_NUM) * 1000 + vpar(45)      /* oby reset here
              if ts(a1,ISOLATED) = 1
                jtype = "I"
              end
              jscrdat = ""
              perform putobj
              jcode = 5 - sigflag
              oby = ts(a1,STAFF_NUM) * 1000 + oby1
              if ts(a1,ISOLATED) = 1
                jtype = "I"
              end
              jscrdat = ""
              perform putobj
              if sigflag = 0
                sigflag = 1
              end
              goto VT2
            end



                This code added 10-12-96



     Put out mark for tie terminator

            if a3 = TIE_TERM
              jtype = "M"
              jcode = 0
              obx = obx1 + hpar(81) + hpar(45)   /* guarenteed to put you beyond bar line
              oby = 0
              pcode = 0
              c7 = ts(a1,BACKTIE)
              c7 = ts(c7,BACKTIE)
              out = "1 " // chs(tiearr(c7,TIE_SNUM))
              jscrdat = ""
              perform putobj

      Now put out the Tie Super-object

         compute sitf (situation flag)

         Description of sitf:   range 1 to 16
 
         If the range were from 0 to 15, then bits 3 to 0
           would have the following meanings:
 
                           zero          |         one
                    --------------------------------------------
           bit 3:        tips down       |       tips up
           bit 2:      note on space     |     note on line
           bit 1:   no stem interfenence |   stem interference
           bit 0:    staff interference  | no staff interference

              c9 = tiearr(c7,TIE_VLOC)
              c10 = tiearr(c7,TIE_FHDIS)        /* local x-offset for first note
              c11 = 0                           /* local x-offset for second note
              c12 = tiearr(c7,TIE_FORCE)        /* force flag
              if c12 = 3
                c12 = 9
              end

            Rules for single note

              c5 = tiearr(c7,TIE_FSTEM)
              if c5 = 0
                sitf = 9                    /* stem up
              else
                sitf = 1
              end

              if c12 > 0
                sitf = c12                  /* forced situation
              end

              if tiearr(c7,TIE_FSTEM) = UP and sitf < 9
                sitf += 2                   /* stem interference
              end

        Note:  you won't know if there is staff interference until
                    you know the final length of the tie

              c9 += tiearr(c7,TIE_STAFF) * 1000

          /* New code added 04/20/03, modified 05/02/03

              c13 = tiearr(c7,TIE_SUGG) & 0xff000000        /* length data
              c6 =  tiearr(c7,TIE_SUGG) & 0xff0000          /* position flags
              c4 =  tiearr(c7,TIE_SUGG) & 0xff00            /* x data
              c5 =  tiearr(c7,TIE_SUGG) & 0xff              /* y data
              c13 >>= 24
              c6 >>= 16
              c4 >>= 8
              if c4 > 0
                c4 = c4 - 128 * notesize / 10
              end
              if c5 > 0
                c5 = c5 - 128 * notesize / 10
              end
              if bit(2,c6) = 1
                c5 += 10000
              end
              c6 = 0
              if c13 > 0
                c6 = c13 - 128 * notesize / 10
              end

          /* end New code

              c8 = tiearr(c7,TIE_SNUM)

              ++outpnt
              tput [Y,outpnt] H ~c8  T ~c9  ~c10  ~c11  ~c4  ~c5  ~c6  ~sitf  0
              tiearr(c7,TIE_SNUM) = 0
              ts(a1,BACKTIE) = 0
              goto VT2
            end
 
                End of 10-12-96 addition



            if nodtype = MARK
              jtype = "M"
              jcode = 0
              obx = obx1
              oby = 0
              pcode = 0
              if ts(a1,ISOLATED) = 1
                jtype = "I"
              end
              jscrdat = ""
              perform putobj
              goto VT2
            end
*     words
            if nodtype = WORDS
              jtype = "D"
              jcode = 0

              if ttext = "Fine"
                jcode = 9
              end
              if ttext = "fine"
                jcode = 9
              end
              if ttext = "[fine]"
                jcode = 9
              end
              if ttext con " "
                if ttext{1,mpt-1} = "da"
                  jcode = 9
                end
                if ttext{1,mpt-1} = "dal"
                  jcode = 9
                end
                if ttext{1,mpt-1} = "Dal"
                  jcode = 9
                end
                if ttext{1,mpt-1} = "Da"
                  jcode = 9
                end
                if ttext con " da "
                  jcode = 9
                end
              end
              if ttext con "D.C." or ttext con "D. C."
                jcode = 9
              end

              pcode = 1
              a4 = ts(a1,FONT_NUM)
              if a4 = 0
                a4 = mdirfont
              end


 
       This code moved to this location from below, because we need
       to the operative font number for spacing purposes.  10/08/08

              ttext = ttext // pad(4)
              if ttext{1} = "!"
                a4 = int(ttext{2..})
                if ttext{sub} = "|"           /* New 01/17/04: skip over "|"
                  ++sub
                end
                ttext = ttext{sub..}
              end
              ttext = trm(ttext)


              if a3 > 4                 /* (a3 = SIGN_TYPE here)
                c5 = a4
                if a3 < 7

        Introducing optional conversion to ligitures in words  04/22/04

                  if ligit_flag = 1
                    if ttext = "ff"
                      ttext = "f\@f"
                    end
LIGCON2:
                    if ttext con "ffi"
                      ttext{mpt,3} = "\0:"
                      goto LIGCON2
                    end
                    if ttext con "ffl"
                      ttext{mpt,3} = "\0;"
                      goto LIGCON2
                    end
                    if ttext con "ff"
                      ttext{mpt,2} = "\0<"
                      goto LIGCON2
                    end
                    if ttext con "fi"
                      ttext{mpt,2} = "\0="
                      goto LIGCON2
                    end
                    if ttext con "fl"
                      ttext{mpt,2} = "\0>"
                      goto LIGCON2
                    end
                  end
#if AUTOSCR
#else
                  perform kernttext            /* New 04/22/04
#endif
                  perform wordspace

                                                         (reminder)
 │    Inputs:    ttext   = word                       │
 │                  c5   = font number                │
 │               curfont = currently active font      │
 │                                                    │
 │    Outputs:   a5 = space taken up by word          │


                  if a3 = 6
                    a5 /= 2
                  else
                    a5 += 10
                  end
                else



           New code (02/03/08) for determining box size and position
             for Rehearsal numbers or letters (uses c10,c11,c12,c13,c14,c15,c16,c17)

                  if a3 = REH_MARK
                    perform wordspace
                    c12 = 2 * font_base + zero_height / 3           /* displacement to top
                    c13 = font_height - font_base * 2 / 3           /* displacement to bottom
                    c14 = spc(48) / 2                               /* displacement to the left
                    c15 = a5 + (spc(48) * 3 / 5)                    /* displacement to the right
                  end



                  a5 = 0
                end
              end
              if a5 > 0
                temp3 = "W -" // chs(a5)
              else
                temp3 = "W 0"
              end

       This code added 10/01/03 to allow for font = 0 (no print)

              ttext = ttext // pad(4)
              if ttext{1} = "!"
                a4 = int(ttext{2..})
                if ttext{sub} = "|"           /* New 01/17/04: skip over "|"
                  ++sub
                end
                ttext = ttext{sub..}
              end
              ttext = trm(ttext)

                   (moved to location above on 10/08/08)



       More code 02/03/08 for dealing with boxes

              if a3 = REH_MARK and box_flag = 1
                sobl(1) = temp3 // temp // " " // chs(a4) // " " // ttext
                c10 = 1
                c11 = oby1 - c12              /* actual displacement to top
                c12 = oby1 + c13              /* actual displacement to bottom
                c13 = 0 - c14                 /* actual displacement to the left
                c14 = c15                     /* actual displacement to the right

           First put in horizontal lines of the box

                c17 = 0
                if notesize = 6
                  c15 = c13 + 1
                  loop for c16 = 1 to 8
                    ++c10
                    sobl(c10) = "K " // chs(c15) // " " // chs(c11) // " 45"
                    ++c10
                    sobl(c10) = "K " // chs(c15) // " " // chs(c12) // " 45"
                    c15 += 10
                    if c17 = 1
                      c16 = 1000
                    end
                    if c15 > (c14 - 9)
                      c15 = c14 - 9
                      c17 = 1
                    end
                  repeat
                else
                  c15 = c13
                  loop for c16 = 1 to 8
                    ++c10
                    sobl(c10) = "K " // chs(c15) // " " // chs(c11) // " 90"
                    ++c10
                    sobl(c10) = "K " // chs(c15) // " " // chs(c12) // " 90"
                    if c17 = 1
                      c16 = 1000
                    end
                    c15 += 30
                    if c15 > (c14 - 30)
                      c15 = c14 - 30
                      c17 = 1
                    end
                  repeat
                end

              for glyph 45                    for glyph 90                         for glyph 89
            ---------------                 ---------------                     -----------------
               notesize 6    -1  0  10        notesize 6       0  0  30            notesize 6         0  0  1  (6)
               notesize 14   -3  0  24        notesize 14      0  1  30            notesize 14        0  1  2  (14)
               notesize 16   -3  0  28        notesize 16      0  1  30            notesize 16        0  1  2  (16)
               notesize 18   -4  0  32        notesize 18      0  1  30            notesize 18        0  1  3  (18)
               notesize 21   -4  0  35        notesize 21      0  2  30            notesize 21        0  1  4  (21)



           Now put in vertical lines of the box

                c17 = 0
                c15 = c11
                --c14
                if notesize > 6
                  --c14
                end
                if notesize > 16
                  --c14
                end
                if notesize > 18
                  --c14
                end

                loop for c16 = 1 to 8
                  ++c10
                  sobl(c10) = "K " // chs(c13) // " " // chs(c15) // " 89"
                  ++c10
                  sobl(c10) = "K " // chs(c14) // " " // chs(c15) // " 89"
                  if c17 = 1
                    c16 = 1000
                  end
                  c15 += notesize
                  if c15 > (c12 - notesize)
                    c15 = c12 - notesize
                    c17 = 1
                  end
                repeat
                pcode = c10
              else

           Need to make a cludge of a modification here 01/12/09.  The problem
           is that when the node is isolated, any non-null xposi_shift becomes
           irrelevant, once mskpage takes over.  In this case, if we want the
           word shifted horizontally, the shift must be in the Word sub-object,
           not in the object position.  We will adjust the obx position because
           it is relevant when printing individual parts

                if ts(a1,ISOLATED) = 1
                  temp3 = "W " // chs(save_xposi_shift) // temp // " " // chs(a4) // " " // ttext
                  obx1 -= save_xposi_shift
                else
                  temp3 = temp3 // temp // " " // chs(a4) // " " // ttext
                end

                sobl(1) = ""
              end


           End of 02/03/08 Changes

              obx = obx1
              oby = ts(a1,STAFF_NUM) * 1000
              if ts(a1,ISOLATED) = 1
                jtype = "I"
              end
              jscrdat = ""
              perform putobj
              goto VT2
            end
*     multi-letter dynamics
            jtype = "S"
            jcode = 0
            pcode = len(ttext)

            putc pcode = ~pcode   ttext = ~ttext |

            obx = obx1
            oby = oby1
            x = obx
            y = oby
            loop for a4 = 1 to pcode
              if "pmfszr" con ttext{a4}
                z = mpt + 107             /* music font
                mpt += 59
                kscrdat = ""
                perform subj
                x += hpar(mpt)
              end
            repeat
            oby = ts(a1,STAFF_NUM) * 1000 + oby
            if ts(a1,ISOLATED) = 1
              jtype = "I"
            end
            jscrdat = ""
            perform putobj

       put out super-objects

VT2:        a2 = ts(a1,SUPER_TYPE)
            if a2 > 0
              a2 /= 2
              if rem = 0 and a2 >= 1 and a2 <= 6
                a4 = save_a4                              /* this was computed above
                if a2 = WEDGES
*        wedges
                  line = chs(smusdir(a4,2)) // " "
                  line = line // chs(ts(a1,WEDGE_SPREAD)) // " "
                  line = line // chs(smusdir(a4,3)) // " " // chs(smusdir(a4,4)) // " "
                  line = line // chs(ts(a1,WEDGE_OFFSET) + obx2) // " " // chs(smusdir(a4,4))

                  ++outpnt
                  tput [Y,outpnt] H ~smusdir(a4,1)  W ~line
                end
                if a2 = DASHES
*        dashes
                  if ts(a1,SIGN_TYPE) = LETTER_DYNAM
                    a6 = obx2 - (2 * hpar(46))
                  else
                    a6 = obx2
                  end
                  line = chs(a6) // " " // chs(smusdir(a4,4)) // " 0"
                  a6 = smusdir(a4,3)
                  ++outpnt
                  tput [Y,outpnt] H ~smusdir(a4,1)  D ~smusdir(a4,2)  ~line  ~a6
                end
*        range shifts
                if chr(a2) in [OCT_UP,OCT_DOWN,DBL_OCT_UP,DBL_OCT_DOWN]
                  if a2 = OCT_UP or a2 = DBL_OCT_UP
                    a5 = smusdir(a4,4) + vpar(47)
                  else
                    a5 = smusdir(a4,4) - vpar(46)
                  end
                  line = chs(smusdir(a4,2)) // " " // chs(smusdir(a4,3)) // " "
                  a6 = obx2 - hpar(47)
                  line = line // chs(a6) // " " // chs(a5) // " " // chs(vpar(41))
                  ++outpnt
                  tput [Y,outpnt] H ~smusdir(a4,1)  V ~line
                end
                smusdir(a4,1) = 0        /* clear the row for next use
              end
            end
            if ts(a1,DINC_FLAG) > 0
              inctype = ts(a1,DINC_FLAG)
            end
            goto ZZZ
          end

      D. Typeset Figures

          if nodtype = FIGURES
            obx = p

        We need to run a little check here.  If there is an element
        in the ts array that has the same division number and is a note or
        cue-note, then the possibility exist that this object might
        have to be shifted to the right in order to be placed under
        the note (and not under some accidental to the note).

            if ts(a1+1,DIV) = ts(a1,DIV)
              if ts(a1+1,TYPE) = NOTE or ts(a1+1,TYPE) = CUE_NOTE
                obx += ts(a1+1,NODE_SHIFT)
                p   += ts(a1+1,NODE_SHIFT)
                ts(a1+1,NODE_SHIFT) = 0
                if ts(a1+1,SPACING) < ts(a1,MIN_FIG_SPAC)
                  ts(a1+1,SPACING) = ts(a1,MIN_FIG_SPAC)
                end
              end
            end

            a3 = FIG_DATA
            supcnt = 0
*     determine if accidentals precede any figures in this set
            loop for a2 = 1 to 4
              mf(a2) = 0
            repeat
            a10 = FIG_DATA
            loop for a2 = 1 to ts(a1,NUMBER_OF_FIG)
              a4 = ts(a1,a10) + 28  /* tricky code, possible rewrite

     Code added 11/16/03 to deal with parentheses around figures

              if a4 > 1000
                a4 = a4 / 1000
                a4 = rem
              end

              temp = chr(a4)
              if "1389" con temp
                if ts(a1,a10+1) > 0 and ts(a1,a10+1) < 20
                  mf(a2) = a4 - 48
                end
              end
              a10 += 3
            repeat
*     construct sub-objects
            oby = vpar(49)
            y = vpar(49)
            loop for a2 = 1 to ts(a1,NUMBER_OF_FIG)
              a6 = ts(a1,a3)

     Code added 11/16/03 to deal with parentheses around figures

              a10 = 0
              if a6 > 1000
                a10 = a6 / 1000
                a6 = rem
                if a6 = 0
                  a10 = 0
                else
                  if a10 = 1
                    y -= vpar(92)
                    x = obx - hpar(136)
                    if mf(a2) > 0
                      a9 = mf(a2) + 67
                      a9 = hpar(a9)
                      x -= a9
                    end
                    z = 197                   /* music font
                    kscrdat = ""
                    perform subj              /* small left parenthesis
                    y += vpar(92)
                  else
                    if a10 = 3                /* shift down to bracket 3 figures
                      y += (vpar(48) >> 1)
                    end
                    y += vpar(93)
                    x = obx - hpar(138)
                    if mf(a2) > 0
                      a9 = mf(a2) + 67
                      a9 = hpar(a9)
                      x -= a9
                    end
                    z = 69                    /* music font
                    kscrdat = ""
                    perform subj              /* large left parenthesis
                    y -= vpar(93)
                    if a10 = 3
                      y -= (vpar(48) >> 1)
                    end
                  end
                end
              end

              x = obx
              if a6 > 0
                if mf(a2) > 0
                  a9 = mf(a2) + 67
                  a9 = hpar(a9)
                  x = obx - a9
                  z = mf(a2) + 210        /* music font
                else
                  a9 = hpar(66)
                  if a6 = 30
                    z = 220               /* music font
                  else
                    if a6 < 10
                      z = a6 + 199
                    else
                      if a6 < 20
                        z = 200
                        kscrdat = ""
                        perform subj
                        x += a9
                        z = a6 + 189
                      else
                        a9 = a6 + 47
                        a9 = hpar(a9)
                        z = a6 + 190
                      end
                    end
                  end
                end
                kscrdat = ""
                perform subj
                x += a9
                a6 = ts(a1,a3+1)
                if a6 > 0
                  a9 = hpar(66)
                  if a6 < 10
                    z = a6 + 199
                  else
                    if a6 < 20
                      z = 200
                      kscrdat = ""
                      perform subj
                      x += a9
                      z = a6 + 189
                    else
                      a9 = a6 + 47
                      a9 = hpar(a9)
                      z = a6 + 190
                    end
                  end
                  kscrdat = ""
                  perform subj
                  x += a9
                end

     Code added 11/16/03 to deal with parentheses around figures

                if a10 > 0
                  x -= a9
                  if a10 = 1
                    x += hpar(137)
                    y -= vpar(92)
                    z = 198                 /* music font
                    kscrdat = ""
                    perform subj            /* small right parenthesis
                    y += vpar(92)
                  else
                    if a10 = 3                /* shift down to bracket 3 figures
                      y += (vpar(48) >> 1)
                    end
                    x += hpar(139)
                    y += vpar(93)
                    z = 70                  /* music font
                    kscrdat = ""
                    perform subj            /* large right parenthesis
                    y -= vpar(93)
                    if a10 = 3
                      y -= (vpar(48) >> 1)
                    end
                  end
                  x += a9
                end

              end
*       set up for dealing with continuation lines
              if ts(a1,a3+2) = 2
                ++snum
                figarr(a2,FIG_SNUM) = snum
                dv4 = x - obx
                if a6 > 0
                  dv4 += (hpar(66) * 3 / 2)     /* 11/16/03 Experiment: was simply hpar(66)
                end
                figarr(a2,FIG_HOFF1) = dv4
                ++supcnt
                supnums(supcnt) = snum
              end
              if ts(a1,a3+2) = 1
                figarr(a2,FIG_HOFF2) = hpar(77)
                figarr(a2,FIG_READY) = 1
                ++supcnt
                supnums(supcnt) = figarr(a2,FIG_SNUM)
              end
              a3 += 3
              y += vpar(48)
            repeat
*    put out object and sub-objects
            out = chs(supcnt)
            loop for a3 = 1 to supcnt
              out = out // " " // chs(supnums(a3))
            repeat
            supcnt = 0
            jtype = "F"
            jcode = 0
            pcode = sobcnt
            oby = ts(a1,STAFF_NUM) * 1000 + oby

        Now look for print suggestions for this figure object

            putobjpar = 0
            c5 = ts(a1,TSR_POINT)
            pcontrol = ors(tsr(c5){1})                  /* 05/02/03
            px = ors(tsr(c5){3}) << 8
            py = ors(tsr(c5){4}) << 16
            a2 = ors(tsr(c5){2}) << 24
            putobjpar = a2 + px + py + pcontrol         /* Note: order of data has been changed

            jscrdat = ""
            perform putobj
*    write out continuation line super-objects
            loop for a2 = 1 to MAX_FIG
              if figarr(a2,FIG_READY) > 0
                ++outpnt
tput [Y,outpnt] H ~figarr(a2,FIG_SNUM)  F ~a2  ~figarr(a2,FIG_HOFF1)  ~figarr(a2,FIG_HOFF2)  0
                loop for a3 = 1 to 4
                  figarr(a2,a3) = 0
                repeat
              end
            repeat
            a4 = ts(a1,FIG_SPACE)
            if a4 > 0
              p += a4
            end
            if ts(a1,DINC_FLAG) > 0
              inctype = ts(a1,DINC_FLAG)
            end
            goto ZZZ
          end

  =================================================================
                   GENERAL SECTION COMMENT

       At this point, we have only notes (grace, regular and cue)
   and rests (regular and cue) left to typeset.  This is actually
   where the process becomes interesting and can be quite complex.
   For music on the grand staff (the most complex situation)
   there can be as many as ten (MAX_PASS) passes and as many as
   six notes in a single pass (maximum chord size)

       We need to review the way note events are organized in the set
   array and how this relates to the way they are organized in the
   i-files.  In the i-files, the basic unit of organization is the
   object.  An object can contain a note, a set of notes (chord), or a
   rest.  Items which normally attach to notes such as accidentals,
   ornaments, articulations, leger lines, etc., are included as
   sub-objects to the object.  Items which normally connect notes such
   as beams, ties, and slurs, are represented by superobjects.  Among
   the parameters associated with an object are (1) horizontal location,
   (2) space node number, and (3) distance increment flag.

       The first level of organization in the set array is by division.
   A division is a time-location with a measure.  A division may have
   several note events belonging to it (as well as other types of events,
   which, at this point in the program have already been dealt with).
   All members of a division will have the same space node number.
   The first object in a division will have a non-zero distance
   increment flag.  This feature is handled automatically by the
   putobj procedure.

       Within a division, we first find all of the grace notes (and
   grace chord notes).  Since grace notes generally precede regular and
   cue notes, these notes can have non-zero advance-space parameters
   associated with them.  This means that grace notes objects can
   advance the horizontal location pointer.  On the other hand, cue-size
   and regular objects will generally have the same horizontal location
   (except for for shifts to accomodate clashes).

       From the above analysis, we can see that the next level of
   organization in the set array is by general location.  In particular,
   grace notes will tend fall into one or more groups, each having a
   separate general location.  All cue-size and regular notes (and
   rests will have the same general location.

       Finally the lowest level of organization in the set array is by
   actual object.  Only notes of the same chord will share the same
   object.

       We are currently inside a big loop, which begins under the title
   "Processing loop (loop ends at ZZZ)".  The loop itself is initiated
   by the instruction "loop for a1 = 1 to sct".  The variable "spn",
   which is the space node number, is retrieved from storage at the top
   of this loop.  It is based on division number.  We do not need to
   process all notes and rests on a particular division at one time; we
   may proceed down to the next level of organization within the set
   array, which is the general location.  The key variable in
   determining this grouping is the space parameter "SPACING".  The
   first ts(.,.) ROW element of a general location group will have a
   non-zero space parameter, and any other element in such a group will
   have a space parameter = 0.

       In typesetting a group of notes at a general location, the
   following information is required.

       (1) The number of passes (chords or single notes) in the group
       (2) The number of set array elements in each of these passes
       (3) a4 = the spacing parameter for this group
       (4) a2 = index to last element in group
 
                          END OF COMMENT
 
  =================================================================
 

      E. Notes/Rests

          a4 = ts(a1,SPACING)

          if ts(a1,NODE_SHIFT) > 0
            dputc shifting division number ~ts(a1,DIV)  by the amount = ~ts(a1,NODE_SHIFT)
            p += ts(a1,NODE_SHIFT)
          end

          npasses = 1
          a3 = 1
          loop for a2 = a1+1 to sct
            if ts(a2,SPACING) <> 0
              --a2
              pitchcnt(npasses) = a3
              goto XX1
            end
            if ts(a2,TYPE) > NOTE_OR_REST
              --a2
              pitchcnt(npasses) = a3
              goto XX1
            end
            if nodtype = GR_NOTE
              if ts(a2,TYPE) = XGR_NOTE
                ++a3
              else
                pitchcnt(npasses) = a3
                a3 = 1
                ++npasses
              end
            else
              if ts(a2,TYPE) = XNOTE or ts(a2,TYPE) = XCUE_NOTE
                ++a3
              else
                pitchcnt(npasses) = a3
                a3 = 1
                ++npasses
              end
            end
          repeat
XX1:

     Create objects for this node

     a1          = index to first element in node
     a2          = index to last element in node
     npasses     = number of passes (separate chords) in this node
     pitchcnt(.) = size of chord for each pass
     a4          = space parameter (space following this node)



     I. Typeset objects in this node


          c2 = a1 - 1
          loop for a14 = 1 to npasses
            obx = p
            c1 = c2 + 1                       /* top of chord
            c2 = c1 + pitchcnt(a14) - 1       /* bottom of chord
            a3 = ts(c1,STAFF_NUM) + 1         /* staff number
            passnum = ts(c1,PASSNUM)
            oby = ts(c1,OBY)
            ntype = ts(c1,NTYPE)
            ntype = ts(c1,NTYPE) & 0xff       /* new 10/15/07
            opt_rest_flag = ts(c1,NTYPE) >> 8 /* new 10/15/07
            nodtype = ts(c1,TYPE)



     I. Construct Text Sub-Object (new to this position  06-26-94 )

            if nodtype = NOTE
              c5 = ts(c1,TEXT_INDEX)
              if c5 > 0
                ttext = tsdata(c5) // pad(1)
              else
                ttext = pad(1)
              end

              if ttext{1} in ['A'..'Z','a'..'z','!'..'(','\','=']


         New test for text data 09/01/03

              c5 = 0
              if ttext{1} in ['A'..'Z','a'..'z','!'..'(','\','=']
                c5 = 1
              else
                ttext = ttext // " "
                loop for c4 = 1 to len(ttext)
                  if ttext{c4} = "|" and ttext{c4+1} in ['A'..'Z','a'..'z','!'..'(','\','=']
                    c5 = 1
                    c4 = len(ttext)
                  end
                repeat
                ttext = trm(ttext)
              end
              if c5 = 1

         End of test 09/01/03

                c5 = mtfont
                perform spacepar
                temp2 = ttext
                if temp2 con "$$$$"
                  ttext = temp2{1,sub-1}
                  c4 = int(temp2{sub+4..})        /* x offset (calculated earlier)
                  if sub < len(temp2)
                    org_c4 = int(temp2{sub+1..})  /* original "unbiased" (pre 12/09/03) offset
                  else
                    org_c4 = c4
                  end
                else
                  dputc Program Error
                end
                temp2 = ttext // "| "
                ttextcnt = 0
CCCD:
                if temp2 con "|"
                  ttext = temp2{1,mpt-1}

                  if ttext = "_"             /* 09/01/03 Must flag isolated "_"
                    ttext = "&"
                  end

                  temp2 = temp2{mpt+1..}
                  ++ttextcnt
                  ttextarr(ttextcnt) = trm(ttext)
                  goto CCCD
                end
                loop for a7 = 1 to ttextcnt

                  ttext = ttextarr(a7)

   determine values of xbytearr

                  a6 = len(ttext)
                  xbytearr(a7) = "* "
                  if "-_" con ttext{a6}
                    ttext = ttext{1,a6-1}
                    xbytearr(a7) = "-_"{mpt} // " "
                    if mpt = 2
                      a6 = len(ttext)
                      if ",.;:!?" con ttext{a6}
                        ttext = ttext{1,a6-1}
                        xbytearr(a7) = ",.;:!?"{mpt} // " "
                      end
                    end
                  end
                  ttextarr(a7) = ttext
                repeat

    determine relative position of ttext

                x = p - c4
                sobx = x - obx

           Code added 12/09/03

                if org_c4 <> c4
                  a8 = p - org_c4
                  sobx2 = a8 - obx
                else
                  sobx2 = 0
                end

                loop for a8 = 1 to ttextcnt
                  ttext = ttextarr(a8)

                  if ttext <> "&"              /* 09/01/03  Use flag set above
                    ++sobcnt

           Code modified 12/09/03

                    if sobx2 <> 0
                      temp3 = "T " // chs(sobx) // "|" // chs(sobx2) // " " // chs(a8) // " "
                    else
                      temp3 = "T " // chs(sobx) // " " // chs(a8) // " "
                    end
                    temp3 = "T " // chs(sobx) // " " // chs(a8) // " "

                    if ttext con "="
                      if mpt < 3               /* 10/19/03  Fixing corner case error
                        ttext{mpt} = "-"
                      else
                        if ttext{mpt-2,3} <> "\0="
                          ttext{mpt} = "-"
                        end
                      end
                    end

        Introducing optional conversion to ligitures in text  10/20/03

                    if ligit_flag = 1
LIGCON1:
                      if ttext con "ffi"
                        ttext{mpt,3} = "\0:"
                        goto LIGCON1
                      end
                      if ttext con "ffl"
                        ttext{mpt,3} = "\0;"
                        goto LIGCON1
                      end
                      if ttext con "ff"
                        ttext{mpt,2} = "\0<"
                        goto LIGCON1
                      end
                      if ttext con "fi"
                        ttext{mpt,2} = "\0="
                        goto LIGCON1
                      end
                      if ttext con "fl"
                        ttext{mpt,2} = "\0>"
                        goto LIGCON1
                      end
                    end
#if AUTOSCR
#else
                    perform kernttext          /* New 04/22/04
#endif
                    perform wordspace
                    sobl(sobcnt) = temp3 // ttext // " " // xbytearr(a8) // chs(a5)
                  end

                repeat
              else
                if ttext in [' ','~']             /* code added 02-23-95
                  loop for c15 = len(ttext) to 1 step -1
                    if ttext{c15} = "~"

         I'm going to try something risky here, namely to add a text sub-object
           to the previous note: temp variables c13,c14,c15

                      loop for c13 = outpnt to 1 step -1
                        tget [Y,c13] temp3
                        if temp3{1,3} = "J N"

                   1. Increment field 6 of record at c13

                          temp3 = temp3{5..}
                          c14 = int(temp3)
                          c14 = int(temp3{sub..})
                          c14 = int(temp3{sub..})
                          temp2 = "J N " // temp3{1..sub}

                          c14 = int(temp3{sub..})
                          ++c14
                          temp2 = temp2 // chs(c14) // temp3{sub..}
                          tput [Y,c13] ~temp2

                   2. Create space at c13+1

                          loop for c14 = outpnt to c13 + 1 step -1
                            tget [Y,c14] temp3
                            tput [Y,c14+1] ~temp3
                          repeat

                   3. Add pseudo text record at c13+1

                          temp3 = "T 0 " // chs(c15) // " ~ * 0"
                          tput [Y,c13+1] ~temp3

                   4. Increment outpnt

                          ++outpnt
                          c13 = 1        /* end of loop
                        end
                      repeat
                    end
                  repeat
                end
              end
            end




            note_dur = ts(c1,NOTE_DUR)        /* Added 11-11-93
            if nodtype <= REST
              passtype = REG
              passsize = FULLSIZE
              if bit(16,ts(c1,SUBFLAG_1)) = 1
                passsize = CUESIZE                /* EXPERIMENT  06-24-94
              end
            else
              passsize = CUESIZE
              if nodtype <= CUE_REST
                passtype = CUE
              else
                passtype = GRACE
              end
            end

      a) rests

            if nodtype = REST or nodtype = CUE_REST
              c3 = ts(c1,STAFF_NUM) * 1000
              perform setrest (c9)                          /*  OK 6-23-93
              goto ZZZZ
            end

      b) arpeggios  (New code 01/13/06)

            if nodtype = GR_NOTE and ntype = ARPEGGIO
              arpeg_flag   = ts(c1,ARPEG_FLAG)
              arpeg_top    = ts(c1,ARPEG_TOP)
              arpeg_bottom = ts(c1,ARPEG_BOTTOM)
              perform setarpeggio
              goto ZZZZ
            end

      c) notes

         leger lines  hpar(82) =  width of black note (for typesetting)
                      hpar(83) =  width of whole note (for typesetting)

            c7 = c2
            c8 = c1
            c9 = 0
            stem = bit(1,ts(c1,STEM_FLAGS))
            if stem = UP
              chord_spread = ts(c2,STAFFLOC) - ts(c1,STAFFLOC)
            else
              chord_spread = ts(c1,STAFFLOC) - ts(c2,STAFFLOC)
            end
            super_flag = 0
            slur_flag = 0
            loop for c3 = c1 to c2
              super_flag |= ts(c3,SUPER_FLAG)
              slur_flag  |= ts(c3,SLUR_FLAG)
            repeat
            if ntype > HALF
              c9 = hpar(83) - hpar(82) + 1
            end
            perform setleger                      /* looks O.K. 6-24-93

         accidentals

            loop for c3 = c1 to c2
              c4 = ts(c3,AX)
              if c4 > 0
                y = ts(c3,STAFFLOC)
                perform setax                     /* looks O.K. 6-24-93
              end
            repeat

         note heads and dots

            z1 = 50 - ntype               /* music font
            if z1 > 43                    /* music font
              z1 = 43                     /* music font
            end
            if passsize = CUESIZE
              z1 += 128                   /* music font
            end

         Adding code for percussion note heads 02/19/06

            c4 = ts(c1,SUBFLAG_1) & 0xf00000
            if c4 > 0
              c4 >>= 20
              if c4 = 1
                z1 = 1001                 /* extended music font
                if passsize = CUESIZE
                  ++z1                    /*
                end
              end
            end


            loop for c3 = c1 to c2
              if c3 = c1

                               All New code 05/02/03

        At this point, we need to see if the note object position has been modified
        "absolutely" by a print suggestion.  If this is the case, we need to make the
        adjustment here, AND, elimate the suggestion from the tsr string.

                c4 = ts(c1,TSR_POINT)
                c5 = ors(tsr(c4){2})
                if bit(0,c5) = 1
                  px = ors(tsr(c4){3})
                  if px > 0
                    px = px - 128 * notesize / 10
                    pxx = c5 & 0x02 >> 1
                    if pxx = 1
                      ts(c1,GLOBAL_XOFF) = px
                      tsr(c4){3} = chr(0)           /* here is where suggestion is zeroed out
                    end
                  end
                end

        End of new code 05/02/03

                obx = ts(c1,GLOBAL_XOFF) + p
              end
              x = obx + ts(c3,LOCAL_XOFF)
              y = ts(c3,STAFFLOC)
              z = z1

     Adding code 11/26/06 to allow for mixed colors in chords

              if mixed_color_flag > 0
                z = 50 - ts(c3,NTYPE)
                if z > 43                                 /* music font
                  z = 43                                  /* music font
                end                                       /* music font
                if passsize = CUESIZE
                  z += 128
                end                                       /* music font
              end

             End of 11/26/06 Addition

              kscrdat = ""
#if AUTOSCR
              perform build_note_kscrdat
#endif

  │                Uses inputs: c3       = pointer into set array for this note
 │                             y        = vertical position of note
 │                             ntype    = type of note (e.g. sixteenth)
 │                             note_dur = duration of note (in divisions)
 │                             divspq   = divspq
 │                             nodtype  = NOTE, GR_NOTE, or CUE_NOTE
  │                Output:  kscrdat string
  │                Operation:  Compute full values for:    P2 P4 P6 P7 P10 P12
 │                            Compute partial values for: P5 P9
 │                            Not computed:               P3 P8
 │
              perform subj
              c16 = y / notesize
              if c16 <= 0
                --c16        /* guarentee c16 is above position for rem <> 0
              end

              c10 = rem
              if y <= 0 - notesize
                if c10 <> 0
                  y += vpar(1)
                  y = c16 + 1 * notesize
                end
                perform wideleger         /* looks O.K. 6-24-93
              end
              if y >= vpar(10)
                if c10 <> 0
                  y -= vpar(1)
                  y = c16 * notesize
                end
                perform wideleger
              end
              perform setdots             /* looks O.K. 6-24-93
            repeat

         look for forward tie, slur and tuplet super-objects

            x = obx
            y = oby
            perform superfor              /* operates on entire chord

         set certain articulations above or below notes or stems

            perform setart                /* operates on entire chord

         if there are slurs entering or leaving this chord, adjust virtual
            endpoints at this time.

            c14 = ts(c1,SLUR_X)
            c8 = 0                          /* slur present flag
            if c14 > 0
              c5 = ts(c14,1)
              c4 = ts(c14,3)
              if c4 <> c5
                c8 = 2                      /* slur present above (usually)
              end
              if c4 < c5
                c5 = c4                     /* above
              end
              c4 = ts(c14,2)
              c6 = ts(c14,4)
              if c4 <> c6
                c8 = 1                      /* slur present below (usually)
              end
              if c6 > c4
                c4 = c6                     /* below
              end
              if stem = DOWN
                c6 = c4
                c4 = c5
                c5 = c6
                if c8 <> 0
                  c8 = 3 - c8
                end
              end
              loop for c6 = c1 to c2
                ts(c6,VIRT_STEM) = c5
                ts(c6,VIRT_NOTE) = c4
              repeat
            else
              c5 = ts(c1,VIRT_STEM)
              c4 = ts(c1,VIRT_NOTE)
            end

         Set more indications

            perform setperf               /* operates on entire chord

         Set forte and piano (New code 05/17/03)

            c17 = ( ts(c1,SUBFLAG_1) | ts(c1,ED_SUBFLAG_1) ) & 0x1c003c00  /* changed 10/08/08 from 0x3c00
            if c17 > 0
              c7 = stem
              px = 0
              py = 0
              pyy = 0
              pxx = 0
              c5 = 14                       /* dynamics code = 14
              perform getpxpy (c5,c1)

              if bit(0,pcontrol) = 1
                if bit(1,pcontrol) = 1
                  if bit(2,pcontrol) = 0
                    c7 = 1 - stem
                  else
                    c7 = stem
                  end
                end
              end

              c5 = ts(c1,VIRT_STEM)
              c4 = ts(c1,VIRT_NOTE)
              c13 = 0
              perform yadjust
              if c7 = stem
                if stem = DOWN
                  y = c5 + vpar(5)
                else
                  y = c4 + vpar(5)
                end
              else
                if stem = UP
                  y = c5 - vpar(2)
                else
                  y = c4 - vpar(2)
                end
              end
              x = obx + px
              if pyy = 1
                y = py
              else
                y += py
              end
              c7 = c17 >> 10

              New code 10/08/08

              if c7 > 15
                c7 >>= 16
                c7 += 15                    /* potential range 1 to 23
              end


              c17 = ts(c1,ED_SUBFLAG_1) & 0x1c003c00  /* changed 10/08/08 from 0x3c00

         Case I: regular dynmaics

              if c17 = 0

             New code 10/08/08 and 01/12/09 and 03/16/09

                if c7 = 16 or c7 = 17 or c7 = 18
                  if c7 = 18             /* sff
                    z = 111               /* music font
                    kscrdat = ""
                    perform subj
                    x += hpar(63)
                    z = 110               /* music font
                    perform subj
                    x += hpar(62)
                    z = 110               /* music font
                    perform subj
                  else
                    if c7 = 16
                      z = 110
                      kscrdat = ""
                      perform subj       /* f
                      x += hpar(140)
                    else
                      z = 109
                      kscrdat = ""
                      perform subj       /* m
                      x += hpar(60)
                      z = 110
                    end
                    perform subj
                    x += hpar(140)       /* f
                    z = 108
                    perform subj
                    x += hpar(62)        /* p
                  end

                else
                  if c7 < 5                   /* p, pp, ppp, pppp
                    z = 108
                    kscrdat = ""
                    loop while c7 > 0
                      perform subj
                      x += hpar(60)
                      --c7
                    repeat
                  else
                    if c7 < 9                 /* f, ff, fff, ffff
                      z = 110
                      kscrdat = ""
                      loop while c7 > 4
                        perform subj
                        x += hpar(140)
                        --c7
                      repeat
                    else
                      if c7 < 11              /* mp, mf
                        z = 109                   /* music font
                        kscrdat = ""
                        perform subj
                        x = obx + hpar(60) + px
                        z = c7 * 2 + 90           /* music font
                        perform subj
                      else
                        if c7 = 11            /* fp
                          z = 110                 /* music font
                          kscrdat = ""
                          perform subj
                          x = obx + hpar(140) + px
                          z = 108                 /* music font
                          perform subj
                        else
                          if c7 = 12          /* sfp
                            z = 111               /* music font
                            kscrdat = ""
                            perform subj
                            x = obx + hpar(63) + px
                            z = 110               /* music font
                            perform subj
                            x += hpar(140)
                            z = 108               /* music font
                            perform subj
                          else
                            kscrdat = ""
                            if c7 > 13          /* sfz, rfz
                              z = c7 * 2 + 83       /* music font
                              perform subj
                              c8 = z - 48
                              x = obx + hpar(c8) + px
                            end
                            z = 110                 /* music font
                            perform subj
#if SFZ
                            x += hpar(62)
                            z = 112                 /* music font
                            perform subj
#endif
                          end
                        end
                      end
                    end
                  end
                end
              else

         Case II: editorial dynamics



       Conditional code added 02/04/04 to implement Roman editorial dynamics

#if ROMAN_EDIT
                ++sobcnt
                sobx = x - obx
                soby = y - oby

             New code 10/08/08

                if c7 = 16
                  sobl(sobcnt) = "W " // chs(sobx) // " " // chs(soby) // " 31 ffp"


                else
                  if c7 < 5                   /* p, pp, ppp, pppp
                    sobl(sobcnt) = "W " // chs(sobx) // " " // chs(soby) // " 31 "
                    loop while c7 > 0
                      sobl(sobcnt) = sobl(sobcnt) // "p"
                      --c7
                    repeat
                  else
                    if c7 < 9                 /* f, ff, fff, ffff
                      sobl(sobcnt) = "W " // chs(sobx) // " " // chs(soby) // " 31 "
                      loop while c7 > 4
                        sobl(sobcnt) = sobl(sobcnt) // "f"
                        --c7
                      repeat
                    else
                      if c7 < 11              /* mp, mf
                        sobl(sobcnt) = "W " // chs(sobx) // " " // chs(soby) // " 31 m"
                        if c7 = 9
                          sobl(sobcnt) = sobl(sobcnt) // "p"
                        else
                          sobl(sobcnt) = sobl(sobcnt) // "f"
                        end
                      else
                        if c7 = 11            /* fp
                          sobl(sobcnt) = "W " // chs(sobx) // " " // chs(soby) // " 31 fp"
                        else
                          if c7 = 12          /* sfp
                            sobl(sobcnt) = "W " // chs(sobx) // " " // chs(soby) // " 31 sfp"
                          else
                            if c7 > 13          /* sfz, rfz
                              if c7 = 14
                                sobl(sobcnt) = "W " // chs(sobx) // " " // chs(soby) // " 31 sf"
                              else
                                sobl(sobcnt) = "W " // chs(sobx) // " " // chs(soby) // " 31 rf"
                              end
#if SFZ
                              sobl(sobcnt) = sobl(sobcnt) // "z"
#endif
                            end
                          end
                        end
                      end
                    end
                  end
                end
#else

         Editorial dynamics using square brackets and the music font



  hpar(108) =  width of editorial dynamic letter p    chr(251)
  hpar(109) =  width of editorial dynamic letter m    chr(252)
  hpar(110) =  width of editorial dynamic letter f    chr(253)
  hpar(111) =  width of editorial dynamic letter s    chr(246)
  hpar(112) =  width of editorial dynamic letter z    chr(247)
  hpar(113) =  width of editorial dynamic letter r    chr(248)
  hpar(114) =  backup to print square bracket for editorial p   [p...   chr(195)
  hpar(115) =  backup to print square bracket for editorial m   [m...
  hpar(116) =  backup to print square bracket for editorial f   [f...
  hpar(117) =  backup to print square bracket for editorial s   [sf
  hpar(118) =  backup to print square bracket for editorial r   [rf
  hpar(119) =  shift to print square bracket following editorial f   f]   chr(196)
  hpar(120) =  shift to print square bracket following editorial p   p]
  hpar(121) =  shift to print square bracket following editorial z   z]

  vpar(84) =  vertical shift up for printing square brackets for dynamics


             New code 10/08/08

                if c7 = 16
                  kscrdat = ""
                  x -= hpar(116)
                  y -= vpar(84)
                  z = 195
                  perform subj
                  x += hpar(116)
                  y += vpar(84)
                  z = 253                     /* editorial f
                  perform subj       /* f
                  x += hpar(110)
                  perform subj       /* f
                  x += hpar(110)
                  perform subj       /* p
                  x += hpar(108)
                  x += hpar(120)

                else

                  if c7 < 5                   /* p, pp, ppp, pppp
                    kscrdat = ""
                    x -= hpar(114)
                    y -= vpar(84)
                    z = 195
                    perform subj
                    x += hpar(114)
                    y += vpar(84)
                    z = 251                       /* editorial p
                    loop while c7 > 0
                      perform subj
                      x += hpar(108)
                      --c7
                    repeat
                    x += hpar(120)
                  else
                    if c7 < 9                 /* f, ff, fff, ffff
                      kscrdat = ""
                      x -= hpar(116)
                      y -= vpar(84)
                      z = 195
                      perform subj
                      x += hpar(116)
                      y += vpar(84)
                      z = 253                     /* editorial f
                      loop while c7 > 4
                        perform subj
                        x += hpar(110)
                        --c7
                      repeat
                      x += hpar(119)
                    else
                      if c7 < 11              /* mp, mf
                        kscrdat = ""
                        x -= hpar(115)
                        y -= vpar(84)
                        z = 195
                        perform subj
                        x += hpar(115)
                        y += vpar(84)
                        z = 252                   /* editorial m
                        perform subj
                        x += hpar(109)
                        if c7 = 9
                          z = 251                 /* editorial p
                          perform subj
                          x += hpar(108)
                          x += hpar(120)
                        else
                          z = 253                 /* editorial f
                          perform subj
                          x += hpar(110)
                          x += hpar(119)
                        end
                      else
                        if c7 = 11            /* fp
                          kscrdat = ""
                          x -= hpar(116)
                          y -= vpar(84)
                          z = 195
                          perform subj
                          x += hpar(116)
                          y += vpar(84)
                          z = 253                 /* editorial f
                          perform subj
                          x += hpar(110)
                          z = 251                 /* editorial p
                          perform subj
                          x += hpar(108)
                          x += hpar(120)
                        else
                          if c7 = 12          /* sfp
                            kscrdat = ""
                            x -= hpar(117)
                            y -= vpar(84)
                            z = 195
                            perform subj
                            x += hpar(117)
                            y += vpar(84)
                            z = 246               /* editorial s
                            perform subj
                            x += hpar(111)
                            z = 253               /* editorial f
                            perform subj
                            x += hpar(110)
                            z = 251               /* editorial p
                            perform subj
                            x += hpar(108)
                            x += hpar(120)
                          else
                            if c7 > 13          /* sfz, rfz
                              kscrdat = ""
                              if c7 = 14
                                x -= hpar(117)
                                y -= vpar(84)
                                z = 195
                                perform subj
                                x += hpar(117)
                                y += vpar(84)
                                z = 246           /* editorial s
                                perform subj
                                x += hpar(111)
                              else
                                x -= hpar(118)
                                y -= vpar(84)
                                z = 195
                                perform subj
                                x += hpar(118)
                                y += vpar(84)
                                z = 248           /* editorial r
                                perform subj
                                x += hpar(113)
                              end
                              z = 253             /* editorial f
                              perform subj
                              x += hpar(110)
#if SFZ
                              z = 247             /* editorial z
                              perform subj
                              x += hpar(112)
#else
                              x += hpar(119)
#endif
                            end
                          end
                        end
                      end
                    end
                  end
                end
                kscrdat = ""
                y -= vpar(84)
                z = 196
                perform subj
#endif

      End of Conditional compile 02/04/04

              end
            end

         End of New code 05/17/03

            loop for c3 = c1 to c2
              ts(c3,VIRT_NOTE) = c4
              ts(c3,VIRT_STEM) = c5
            repeat

         set stems and beams for this note

            if stem = UP
              c3 = c1
            else
              c3 = c2
            end
            perform setstem        /* (revised for multiple notes)

         determine super-objects which end on this note or which
             contain this note (such as beams)

          1) beams

            if ts(c1,BEAM_FLAG) > 0
              ++supcnt
              supnums(supcnt) = beampar(passtype,passnum,BM_SNUM)
            end

          2) ties which end on this note

            loop for c3 = c1 to c2
              c7 = ts(c3,BACKTIE)
              if c7 > 0
                if c7 < INT10000         /* c7 = index to ts element which starts the tie
                  c7 = ts(c7,BACKTIE)    /* c7 now points to ROW of tiearr
                else
                  c7 -= INT10000
                end
                ++supcnt
                supnums(supcnt) = tiearr(c7,TIE_SNUM)
              end
              ts(c3,BACKTIE) = c7        /* now set BACKTIE to point directly to ROW of tiearr
            repeat

          3) slurs      (revised for multiple notes)

            loop for c4 = 1 to 4
              c5 = c4 * 2 - 1
              if bit(c5,slur_flag) = 1
                ++supcnt
                supnums(supcnt) = slurar(c4,SL_SNUM)
              end
              if bit(c5+16,slur_flag) = 1
                ++supcnt
                supnums(supcnt) = slurar(c4+4,SL_SNUM)
              end
            repeat

          4) tuplets    (revised for multiple notes)

            if bit(5,super_flag) = 1
              ++supcnt
              supnums(supcnt) = tuar(passtype,passnum,TU_SNUM)
            end

          5) long trills     (revised for multiple notes)

            if tsnum(passnum) > 0 and bit(3,super_flag) = 1    /* long trill ending
              ++supcnt
              supnums(supcnt) = tsnum(passnum)
            end

     New code (11-11-93)  Duration attribute of note

            ++sobcnt
            sobl(sobcnt) = "A D " // chs(note_dur) // " " // chs(divspq*4)

     Write out Object Record and associated Sub-Objects

            out = chs(supcnt)
            loop for c4 = 1 to supcnt
              out = out // " " // chs(supnums(c4))
            repeat
            if nodtype = GR_NOTE or nodtype = XGR_NOTE
              jtype = "G"
            else
              jtype = "N"
            end
            jcode = ntype
            pcode = sobcnt
            c10 = ts(c1,STAFF_NUM) * 1000
            oby += c10

        Now look for print suggestions for this note object

            putobjpar = 0
            c4 = ts(c1,TSR_POINT)
            pcontrol = ors(tsr(c4){1})                  /* 05/02/03
            px = ors(tsr(c4){3}) << 8
            py = ors(tsr(c4){4}) << 16
            c8 = ors(tsr(c4){2}) << 24
            putobjpar = c8 + px + py + pcontrol         /* Note: order of data has been changed

            if xdata_flag = 1
              c4 = ts(c1,STEM_FLAGS) & 0x07       /* first three flags
              c4 <<= 4
              putobjpar |= c4

        Need to add in the effects of some extra x-position
        modifications.  11/24/07

              c4 = ts(c1,GLOBAL_XOFF)                   /* ???? I worry about this

              t1 = putobjpar >> 8   & 0xff
              if t1 > 0
                t1 = t1 - 128 * notesize / 10
              end
              c4 = ts(c1,GLOBAL_XOFF) + t1              /* I worry less about this
                                                        /* and I think I may have it fixed.
              jscrdat = ""
              if c4 > 0
                jscrdat = "| P3=" // chs(c4)
              else
                if c4 < 0
                  c4 = 0 - c4
                  jscrdat = "| P3=-" // chs(c4)
                end
              end
            end

            perform putobj
            oby -= c10

     Write out completed Super-Objects and set up new ones

       1) Tuples

            if bit(5,super_flag) = 1      /*  (revised for multiple notes)

      Code added 05-31-95 to prevent tuplets over "partial" beams from being
         associated with those beams.

              if beampar(passtype,passnum,BM_TUPLE) > 0
                if beampar(passtype,passnum,BM_READY) = 0
                  beampar(passtype,passnum,BM_TUPLE) = 0
                end
              end

              c8 = 1
              t2 = 0
              t1 = (tuar(passtype,passnum,TU_FSTEM) & 0xff) + stem
              c9 = tuar(passtype,passnum,TU_Y1)
              c11 = 0
              goto TPF(tpflag+1)
TPF(1):                                   /* default tuplet placement
              if beampar(passtype,passnum,BM_TUPLE) > 0
                c8 |= 0x08
                t2 = beampar(passtype,passnum,BM_SNUM)
                t1 = oby
                if ts(c1,MULTI_TRACK) > 0
                  c8 |= 0x10
                else
                  t1 += chord_spread
                  c9 = tuar(passtype,passnum,TU_Y2)
                end
                c10 = tuar(passtype,passnum,TU_FSTEM) & 0xff00
                c10 >>= 8
                if bit(0,c10) = 1       /* bracket present 03-21-97
                  c10 >>= 1
                  c10 <<= 5
                  c10 |= 0x02           /* add bracket

                  if beampar(passtype,passnum,BM_TUPLE) = 2    /* this code expanded 05/06/03
                    if bit(4,c8) = 1
                      c10 |= 0x04         /* tips up
                    end
                  else
                    if bit(4,c8) = 0
                      c10 |= 0x04         /* tips up
                    end
                  end

                  if beampar(passtype,passnum,BM_TUPLE) = 2
                    c10 |= 0x04         /* tips up
                  end

                  c8 |= c10
                end
                goto TPFEC
              else
                if t1 = 0
                  goto TPFEA
                else
                  goto TPFEB
                end
              end
TPF(2):                                   /* place tuplet near note heads
              if beampar(passtype,passnum,BM_TUPLE) > 0
                c8 |= 0x08
                t2 = beampar(passtype,passnum,BM_SNUM)
                t1 = oby + chord_spread
                c9 = tuar(passtype,passnum,TU_Y2)
                c10 = tuar(passtype,passnum,TU_FSTEM) & 0xff00
                c10 >>= 8
                if bit(0,c10) = 1       /* bracket present 03-21-97
                  c10 >>= 1
                  c10 <<= 5
                  c10 |= 0x02           /* add bracket
                  if beampar(passtype,passnum,BM_TUPLE) = 1
                    c10 |= 0x04         /* tips up
                  end
                  c8 |= c10
                end
                goto TPFEC
              else
                if t1 = 0
                  goto TPFEA
                else
                  goto TPFEB
                end
              end
TPF(3):                                   /* place tuplet near stems
              if beampar(passtype,passnum,BM_TUPLE) > 0
                c8 |= 0x18
                t2 = beampar(passtype,passnum,BM_SNUM)
                t1 = oby
                c10 = tuar(passtype,passnum,TU_FSTEM) & 0xff00
                c10 >>= 8
                if bit(0,c10) = 1       /* bracket present 03-21-97
                  c10 >>= 1
                  c10 <<= 5
                  c10 |= 0x02           /* add bracket
                  if beampar(passtype,passnum,BM_TUPLE) = 2
                    c10 |= 0x04         /* tips up
                  end
                  c8 |= c10
                end
                goto TPFEC
              else
                if t1 > 0
                  goto TPFEA
                else
                  c11 = hpar(82)          /* shift for stems up
                  goto TPFEB
                end
              end
TPF(4):                                   /* place all tuplets above notes
              if beampar(passtype,passnum,BM_TUPLE) > 0
                t1 = oby
                if stem = UP
                  c8 |= 0x18
                else
                  c8 |= 0x08
                  t1 += chord_spread
                  c9 = tuar(passtype,passnum,TU_Y2)
                end
                t2 = beampar(passtype,passnum,BM_SNUM)
                c10 = tuar(passtype,passnum,TU_FSTEM) & 0xff00
                c10 >>= 8
                if bit(0,c10) = 1       /* bracket present 03-21-97
                  c10 >>= 1
                  c10 <<= 5
                  c10 |= 0x02           /* add bracket
                  c8 |= c10
                end
                goto TPFEC
              else
                if t1 = 0
                  c11 = hpar(82)
                end
                goto TPFEB
              end
TPF(5):                                   /* place all tuplets below notes
              if beampar(passtype,passnum,BM_TUPLE) > 0
                t1 = oby
                if stem = UP
                  c8 |= 0x08
                  t1 += chord_spread
                  c9 = tuar(passtype,passnum,TU_Y2)
                else
                  c8 |= 0x18
                end
                t2 = beampar(passtype,passnum,BM_SNUM)
                c10 = tuar(passtype,passnum,TU_FSTEM) & 0xff00
                c10 >>= 8
                if bit(0,c10) = 1       /* bracket present 03-21-97
                  c10 >>= 1
                  c10 <<= 5
                  c10 |= 0x02           /* add bracket
                  c10 |= 0x04           /* tips up
                  c8 |= c10
                end
                goto TPFEC
              else
                if t1 > 0
                  c11 = hpar(82)
                end
                goto TPFEA
              end

TPFEA:
              c9 = tuar(passtype,passnum,TU_Y2) + notesize
              c9 += vpar(64)
              if t1 > 0
                c9 += vpar(7)
                t1 = vpar(7)                       /* add distance if stem is down
              else
                t1 = 0
              end
              c10 = notesize * 6
              if c9 < c10
                c9 = c10
              end
              t1 += oby + notesize + vpar(64)      /* t1 set above
              if t1 < c10
                t1 = c10
              end
              c10 = tuar(passtype,passnum,TU_FSTEM) & 0xff00
              c10 >>= 8
              if bit(0,c10) = 1       /* bracket present 03-21-97
                c10 >>= 1
                c10 <<= 5
                c10 |= 0x02           /* add bracket
                c10 |= 0x04           /* tips up
                c8 |= c10
              end
              goto TPFEC
TPFEB:
              c9 = tuar(passtype,passnum,TU_Y2) - notesize
              c10 = 0 - vpar(1)           /* OK 4-21-95
              if t1 = 0
                c9 -= vpar(7)
                t1 = 0 - vpar(7)                   /* subtract distance if stem is up
              else
                t1 = 0
              end
              if c9 > c10
                c9 = c10
              end
              t1 += oby - notesize                 /* t1 set above
              if t1 > c10
                t1 = c10
              end
              c10 = tuar(passtype,passnum,TU_FSTEM) & 0xff00
              c10 >>= 8
              if bit(0,c10) = 1       /* bracket present 03-21-97
                c10 >>= 1
                c10 <<= 5
                c10 |= 0x02           /* add bracket
                c8 |= c10
              end
TPFEC:
              c9 -= tuar(passtype,passnum,TU_Y1)
              t1 -= oby
              c13 = ts(c1,TUPLE)

        Convert c13 to 1000 * n1 + n2 and get x,y adjustments    New 11/05/05

              c13 = ts(c1,TUPLE) & 0xffff
              c17 = c13 >> 8
              c13 &= 0xff
              c17 *= 1000
              c13 += c17

              c17 = ts(c1,TUPLE) & 0xff0000       /* x adjustment
              c17 >>= 16
              if c17 > 0
                c16 = c17 - 128                   /* center to zero
              else
                c16 = 0
              end
              c11 += c16

              c17 = ts(c1,TUPLE) & 0xff000000     /* y adjustment
              c17 >>= 24
              if c17 > 0
                c17 = c17 - 128                   /* center to zero
              else
                c17 = 0
              end
              c9 += c17
              t1 += c17

              t3  = tuar(passtype,passnum,TU_SNUM)
              ++outpnt
              tput [Y,outpnt] H ~t3  X ~c8  ~c13  0 ~c9  ~c11  ~t1  ~t2
              tput [Y,outpnt] H ~t3  X ~c8  ~c13  ~c16  ~c9  ~c11  ~t1  ~t2
              tuar(passtype,passnum,TU_SNUM) = 0       /* 05/05/03 adding this (from s2ed)
              tpflag = global_tpflag
            end

       2) Beams           (O.K. for multiple notes)

            if beampar(passtype,passnum,BM_READY) > 0
              if notesize = 6
                if beampar(passtype,passnum,BM_SIZE) = CUESIZE
                  beamfont = 102
                else
                  beamfont = 103
                end
              end
              if notesize = 14
                if beampar(passtype,passnum,BM_SIZE) = CUESIZE
                  beamfont = 106
                else
                  beamfont = 108
                end
              end
              if notesize = 16                  /* size-16 added 12/31/08
                if beampar(passtype,passnum,BM_SIZE) = CUESIZE
                  beamfont = 107
                else
                  beamfont = 109
                end
              end
              if notesize = 18                  /* size-18 added 12/18/04
                if beampar(passtype,passnum,BM_SIZE) = CUESIZE
                  beamfont = 107
                else
                  beamfont = 110
                end
              end
              if notesize = 21
                if beampar(passtype,passnum,BM_SIZE) = CUESIZE
                  beamfont = 109
                else
                  beamfont = 112
                end
              end

              c4 = beampar(passtype,passnum,BM_CNT)
              c5 = 1
              c6 = 0
              c7 = beampar(passtype,passnum,BM_STEM) << 1
              loop for c3 = 1 to c4
                c7 >>= 1
                if c7 & 0x01 <> 1
                  c6 = 1
                end
                c5 <<= 1
              repeat

              c7 += beampar(passtype,passnum,BM_SUGG)        /* New code 05/14/03

              out = chs(c7) // " "               /* first stem direction
              c8 = beampar(passtype,passnum,BM_STEM)
              if c6 = 0 or c8 = 0
                out = out // "0 "                /* consistant stem directions
              else
                if c7 & 0x01 = UP                            /* New code 05/14/03
                  c5 -= 1                        /* c5 = 111 ... for number of notes
                  c8 = not(c8) & c5
                end
                out = out // chs(c8) // " "
              end
              out = out // chs(beamfont) // " "
              out = out // chs(beampar(passtype,passnum,BM_READY))
              loop for c4 = 1 to beampar(passtype,passnum,BM_READY)
                out = out // " "
                out = out // chs(beamdata(passtype,passnum,c4))
              repeat
              ++outpnt
              tput [Y,outpnt] H ~beampar(passtype,passnum,BM_SNUM)  B ~out
              beampar(passtype,passnum,BM_READY) = 0
              beampar(passtype,passnum,BM_TUPLE) = 0
            end

       3) Ties            (revised for multiple notes)

            tiecnt = 0
            loop for c3 = c1 to c2
              c7 = ts(c3,BACKTIE)
              if c7 > 0

         compute sitf (situation flag)

         Description of sitf:   range 1 to 16
 
         If the range were from 0 to 15, then bits 3 to 0
           would have the following meanings:
 
                           zero          |         one
                    --------------------------------------------
           bit 3:        tips down       |       tips up
           bit 2:      note on space     |     note on line
           bit 1:   no stem interfenence |   stem interference
           bit 0:    staff interference  | no staff interference

                c9 = tiearr(c7,TIE_VLOC)
                c10 = tiearr(c7,TIE_FHDIS)        /* local x-offset for first note
                c11 = ts(c3,LOCAL_XOFF)           /* local x-offset for second note
                c12 = tiearr(c7,TIE_FORCE)        /* force flag
                if c12 = 3
                  c12 = 9
                end
                c8 = ts(c3,MULTI_TRACK)
                c6 = c8 >> 2                      /* multi-track flag
                c8 &= 0x03                        /* mcat flag

              Modify multi-track flag under certain conditions
                    ADDED   9-10-93

                if c6 > 0
                  if ts(c3,PASSNUM) = 1 and bit(1,ts(c3,STEM_FLAGS)) = DOWN
                    c6 = 0
                  end
                end

                if c6 = 0
                  if c8 < 2

              Rules for single note (or chord) of single part

                    if bit(2,ts(c3,STEM_FLAGS)) = 0 /* single note
                      c5 = tiearr(c7,TIE_FSTEM) + stem
                      if c5 = 0
                        sitf = 9                    /* both stems up
                      else
                        sitf = 1
                      end

                      if c12 > 0
                        sitf = c12                  /* forced situation
                      end

                      if tiearr(c7,TIE_FSTEM) = UP and sitf < 9
                        sitf += 2                   /* stem interference
                      end
                    else                            /* chord
                      if c3 < c2
                        sitf = 1
                      else
                        sitf = 9
                      end

                      if c12 > 0
                        sitf = c12                  /* forced situation
                      end

                      if sitf = 1
                        if tiearr(c7,TIE_FSTEM) = UP
                          if c10 = 0
                            sitf += 2               /* stem interference
                          end
                        else
                          if stem = DOWN and c3 <> c1
                            if c11 = 0
                              sitf += 2             /* stem interference
                            end
                          end
                        end
                      else
                        if stem = DOWN
                          if c11 = 0
                            sitf += 2               /* stem interference
                          end
                        end
                      end
                    end
                  else

              Rules for chords representing multiple parts

                    if c3 = c2                    /* bottom note of chord
                      sitf = 9
                    else
                      sitf = 1
                    end

                    if c12 > 0
                      sitf = c12                  /* forced situation
                    end

                    if c3 = c2
                      if stem = DOWN
                        sitf += 2                 /* stem interference
                      end
                    else
                      if c3 = c1
                        if tiearr(c7,TIE_FSTEM) = UP
                          sitf += 2               /* stem interference
                        end
                      else
                        if tiearr(c7,TIE_FSTEM) = UP or stem = DOWN
                          sitf += 2               /* stem interference
                        end
                      end
                    end
                  end
                else

              Rules for multiple passes on a staff

                  if c6 = 1
                    sitf = 3
                    if c12 = 9
                      sitf = 11
                    end
                  else
                    if c6 = 2
                      sitf = 11
                      if c12 = 1
                        sitf = 3
                      end
                    else
                      if c6 = 3
                        if stem = UP
                          sitf = 1
                          if c12 > 0
                            sitf = c12            /* forced situation
                          end
                          if tiearr(c7,TIE_FSTEM) = UP
                            sitf += 2
                          end
                        else
                          sitf = 11
                          if c12 = 1
                            sitf = 3
                          end
                        end
                      end
                    end
                  end
                end
                c5 = c9 / notesize
                if rem = 0
                  sitf += 4                    /* note on line
                end

        Note:  you won't know if there is staff interference until
                    you know the final length of the tie

                c9 += tiearr(c7,TIE_STAFF) * 1000

          /* New code added 04/20/03, modified 05/02/03

                c13 = tiearr(c7,TIE_SUGG) & 0xff000000        /* length data
                c6  = tiearr(c7,TIE_SUGG) & 0xff0000          /* position flags
                c4  = tiearr(c7,TIE_SUGG) & 0xff00            /* x data
                c5  = tiearr(c7,TIE_SUGG) & 0xff              /* y data
                c13 >>= 24
                c6 >>= 16
                c4 >>= 8
                if c4 > 0
                  c4 = c4 - 128 * notesize / 10
                end
                if c5 > 0
                  c5 = c5 - 128 * notesize / 10
                end
                if bit(2,c6) = 1
                  c5 += 10000
                end
                c6 = 0
                if c13 > 0
                  c6 = c13 - 128 * notesize / 10
                end

          /* end New code

                c8 = tiearr(c7,TIE_SNUM)

                ++outpnt
                tput [Y,outpnt] H ~c8  T ~c9  ~c10  ~c11  ~c4  ~c5  ~c6  ~sitf  0
                tiearr(c7,TIE_SNUM) = 0
                ts(c3,BACKTIE) = 0
              end

        If there is a tie leaving this note, build
          up a new ROW element of tiearr

              if bit(0,ts(c3,SUPER_FLAG)) = 1
*      identify free slice of tiearr
                loop for c7 = 1 to MAX_TIES
                  if tiearr(c7,TIE_SNUM) = 0
                    goto X2
                  end
                repeat

           Here is where tiearr is built

X2:             ++tiecnt
                tiearr(c7,TIE_SNUM)  = tv4(tiecnt)
                tiearr(c7,TIE_NTYPE) = ts(c3,TYPE)
                tiearr(c7,TIE_VLOC)  = ts(c3,STAFFLOC)
                tiearr(c7,TIE_FHDIS) = ts(c3,LOCAL_XOFF)
                tiearr(c7,TIE_FSTEM) = bit(1,ts(c3,STEM_FLAGS))
                tiearr(c7,TIE_NDX)   = c3
                tiearr(c7,TIE_STAFF) = ts(c3,STAFF_NUM)
                tiearr(c7,TIE_FOUND) = 0
                tiearr(c7,TIE_FORCE) = ts(c3,SLUR_FLAG) >> 24
       /* New code 04/20/03
                c4 = ts(c3,TSR_POINT)
                tiearr(c7,TIE_SUGG)  = ors(tsr(c4){69,4})

                ts(c3,BACKTIE) = c7        /* not used here as a back pointer
              end
            repeat

       4) Slurs           (revised for multiple notes)

            loop for c4 = 1 to 8
              c5 = c4 * 2 - 1
              if c4 > 4
                c5 += 8
              end

      end-slurs
 
        first element
        ────────────────────
           bit 27:     start/end flag (0 = start, 1 = end)
           bits 24-26: slur number - 1 (0 to 7)
           bits 17-23: curvature information (end only)
           bit 16:     up/down flag (0 = tips up, 1 = tips down) (end only)
           bits 0-15:  x-offset + 1000 (always a positive number)
        second element
        ─────────────────────
           y position relative to the staff
        third element (05/06/03)
        ─────────────────────
           print suggestion for this end of the slur

              if bit(c5,slur_flag) = 1
                c14 = ts(c1,SLUR_X)
                loop for c13 = 7 to 31 step 2
                loop for c13 = 7 to (TS_SIZE - 2) step 3     /* 05/06/03
                  c12 = ts(c14,c13)
                  c11 = c12 >> 24
                  if c11 = c4 + 0x0f       /* c4 - 1 + 0x10  (end of slur)
                    c11 = c12 & 0xffff - 1000      /* x-offset
                    c10 = bit(16,c12)              /* up/down flag
                    c9  = c12 & 0x000e0000 >> 17   /* curvature (1 to 4)
                    c8 = ts(c14,c13+1) - ts(c1,OBY) /* y-offset
                    c15 = ts(c14,c13+2)            /* print suggestion at end of slur (05/06/03)
                    c13 = 100                      /* end of loop
                  end
                repeat
                if c13 < 100
                  putc Program error at slur recovery
                  examine
                  stop
                end
                sitf = 0
                if in_line_edslur > 0       /* New condition 01/12/09
                  if c4 > 2
                    sitf = 1                /* dotted slur
                  end
                else
                  if c4 > 4
                    sitf = 1                /* dotted slur
                  end
                end
                if c10 = UP
                  sitf += 12
                end
                c10 = slurar(c4,SL_SNUM)    /* slur number
                c7  = slurar(c4,SL_YSHIFT)  /* starting y-shift
                c6  = slurar(c4,SL_XSHIFT)  /* starting x-shift
                c9 -= 1
                c13 = slurar(c4,SL_BEAMF)   /* 0 = slur doesn't start on a beam
                                            /* 1 = slur starts on a stem up beam
                                            /* 2 = slur starts on a stem down beam
                c16 = slurar(c4,SL_SUGG)    /* print sugg. from beginning of slur (05/06/03)
                c12 = 0
                if c13 > 0
                  if bit(1,ts(c1,BEAM_FLAG)) = 1
                    if stem = UP and c8 < 0 - vpar(6)
                      c12 = 1
                    end
                    if stem = DOWN and c8 > vpar(6)
                      c12 = 2
                    end
                  end
                  if c12 <> c13
                    c12 = 0
                  end
                end

        Incorporate print suggestions for slur (05/06/03)

                if c16 <> 0
                  putc Suggestions from beginning of slur
                  c17 = c16 & 0xff000000 >> 24
                  putc .w6x ~c17 ...
                  c17 = c16 & 0xff0000 >> 16
                  putc .w6x ~c17 ...
                  c17 = c16 & 0xff00 >> 8
                  putc .w6x ~c17 ...
                  c17 = c16 & 0xff
                  putc .w6x ~c17
                  getc
                end

                if c15 <> 0
                  putc Suggestions from end of slur
                  c17 = c15 & 0xff000000 >> 24
                  putc .w6x ~c17 ...
                  c17 = c15 & 0xff0000 >> 16
                  putc .w6x ~c17 ...
                  c17 = c15 & 0xff00 >> 8
                  putc .w6x ~c17 ...
                  c17 = c15 & 0xff
                  putc .w6x ~c17
                  getc
                end


       Code added 04/26/05 to implement suppression of slur printing

                if c16 = -1
                  sitf = 32
                  c16 = 0
                end

                c17 = c16 >> 24                        /* relative x start
                c17 &= 0xff
                if c17 > 0
                  c17 = c17 - 128 * notesize + 5 / 10
                  c6 += c17
                end

                c17 = c16 & 0xff0000 >> 16             /* relative y start
                if c17 > 0
                  c17 = c17 - 128 * notesize + 5 / 10
                  c7 += c17
                end

                c17 = c15 >> 24                        /* relative x end
                c17 &= 0xff
                if c17 > 0
                  c17 = c17 - 128 * notesize + 5 / 10
                  c11 += c17
                end

                c17 = c15 & 0xff0000 >> 16             /* relative y end
                if c17 > 0
                  c17 = c17 - 128 * notesize + 5 / 10
                  c8 += c17
                end

                c17 = c15 & 0xff00 >> 8                /* change to curvature
                if c17 > 0
                  c17 = c17 - 128 * notesize + 5 / 10
                  c9 += c17
                end

                c17 = c16 & 0xff00 >> 8                /* global X shift
                if c17 > 0
                  c17 = c17 - 128 * notesize + 5 / 10
                end

                c16 = c16 & 0xff                       /* global Y shift
                if c16 > 0
                  c16 = c16 - 128 * notesize + 5 / 10
                end

                ++outpnt
                tput [Y,outpnt] H ~c10  S ~sitf  ~c6  ~c7  ~c11  ~c8  ~c9  ~c12  ~c17  ~c16
              end

      beginning-slurs

              --c5
              if bit(c5,slur_flag) = 1
                c14 = ts(c1,SLUR_X)
                loop for c13 = 7 to 31 step 2
                loop for c13 = 7 to (TS_SIZE - 2) step 3     /* 05/06/03
                  c12 = ts(c14,c13)
                  c11 = c12 >> 24
                  if c11 = c4 - 1                  /* c4 - 1  (beginning of slur)
                    c11 = c12 & 0xffff - 1000      /* x-offset
                    c8 = ts(c14,c13+1) - ts(c1,OBY) /* y-offset
                    c15 = ts(c14,c13+2)            /* print suggestion at beginning of slur
                    c13 = 100                      /* end of loop
                  end
                repeat
                if c13 < 100
                  putc Problem finding the end of a slur
                  putc Possible causes:
                  putc   1. A slur has not been closed properly
                  putc   2. Overlapping slurs using the same code
                  putc
                  examine
                  stop
                end
                c12 = 0
                if ts(c1,BEAM_FLAG) > 1
                  if stem = UP and c8 < 0 - vpar(6)
                    c12 = 1
                  end
                  if stem = DOWN and c8 > vpar(6)
                    c12 = 2
                  end
                end
                slurar(c4,SL_SNUM)   = slurar(c4,SL_NEXTSNUM)
                slurar(c4,SL_YSHIFT) = c8
                slurar(c4,SL_XSHIFT) = c11
                slurar(c4,SL_BEAMF)  = c12  /* 0 = slur doesn't start on a beam
                                            /* 1 = slur starts on a stem up beam
                                            /* 2 = slur starts on a stem down beam
                slurar(c4,SL_SUGG)   = c15  /* (05/06/03)
              end
            repeat

       5) Long Trills

            if bit(3,super_flag) = 1 and tsnum(passnum) > 0
              out = "H " // chs(tsnum(passnum)) // " R " // chs(ctrarrf(passnum))
              out = out // " 0"
              ++outpnt
              if nodtype = GR_NOTE or nodtype = XGR_NOTE
                tput [Y,outpnt] ~out  0 ~try(passnum)
              else
                tput [Y,outpnt] ~out  -~hpar(42)  ~try(passnum)
              end
              tsnum(passnum) = 0
              ctrarrf(passnum) = 0
            end
            if pre_tsnum(passnum) > 0                  /* substitute preliminary values
              tsnum(passnum) = pre_tsnum(passnum)
              ctrarrf(passnum) = pre_ctrarrf(passnum)
              try(passnum) = pre_try(passnum)
              pre_tsnum(passnum) = 0
            end
ZZZZ:
          repeat
          p += a4


     Now that you are all done with the notes and rests of
        this node, you may set the new inctype

          if ts(a1,DINC_FLAG) > 0
            inctype = ts(a1,DINC_FLAG)
          end
          a1 = a2
ZZZ:    repeat

     End of processing loop
 *************************************************************

      return

 ┌──────────────────────────────────────────────────────────────────────┐
 │  2a. getpxpy (code,index)     04-08-97 added index variable          │
 │                                                                      │
 │    Purpose:  Save space; get values of px, py, pxx, pyy for          │
 │              position modification                                   │
 │                                                                      │
 │    Inputs:      code = type of subobject referred to                 │
 │                 index = index into ts array                          │
 │                                                                      │
 │    Outputs:     pcontrol                                             │
 │                 px                                                   │
 │                 py                                                   │
 │                 pxx  (1 = absolute, 0 = relative)                    │
 │                 pyy  (1 = absolute, 0 = relative)                    │
 │                                                                      │
 └──────────────────────────────────────────────────────────────────────┘

      procedure getpxpy (code,index)
        int t2,t3
        int code,index

        getvalue code,index

        ++code                                      /* all New code 05/02/03
        code <<= 2
        px = 0
        py = 0
        pxx = 0
        pyy = 0
        t2 = ts(index,TSR_POINT)
        pcontrol = ors(tsr(t2){code-3})
        t3 = ors(tsr(t2){code-2})

        if bit(0,t3) = 1
          px = ors(tsr(t2){code-1})
          if px > 0
            px = px - 128 * notesize / 10
            pxx = t3 & 0x02 >> 1
          end
          py = ors(tsr(t2){code})
          if py > 0
            py = py - 128 * notesize / 10
            pyy = t3 & 0x04 >> 2
          end
        end
      return


 ┌──────────────────────────────────────────────────────────────────────┐
 │P  3. setstem                                                         │
 │                                                                      │
 │    Purpose:  Generate subobjects for note stem, or construct         │
 │              beamdata parameters for setting beam.  When beam        │
 │              is complete, this procedure will call guessbeam.        │
 │                                                                      │
 │    Inputs:      stem = stem direction  (0=UP, 1=DOWN)                │
 │                ntype = type of note                                  │
 │             passtype = type of pass (reg,cue,grace,cuegrace)         │
 │             passsize = size of notes (full size vs. cue-size)        │
 │              passnum = pass number                                   │
 │                  obx = x co-ordinate of object                       │
 │                  oby = y co-ordinate of object                       │
 │                   c1 = pointer to top note head in array             │
 │                   c2 = pointer to bottom note head in array          │
 │                   c3 = pointer to note head at top of stem           │
 │           super_flag = composite of SUPER_FLAGs for this chord       │
 │                                                                      │
 └──────────────────────────────────────────────────────────────────────┘

      procedure setstem
        str temp.80
        int t2,t3,t4,t5,t11,t12,t13,t14,t15
        int bcount

       Determine number of repeaters in "single note" case

        t11 = 0
        if ts(c1,BEAM_FLAG) = NO_BEAM and ts(c1,BEAM_CODE) > 0
          t12 = ts(c1,BEAM_CODE)
          loop
            t12 /= 10
            ++t11
          repeat while t12 > 0
        end

        if ntype >= WHOLE
          if t11 > 0
            y = ts(c1,STAFFLOC) - vpar(3)
            z = 127
            kscrdat = ""
            loop for t12 = 1 to t11
              perform subj
              y -= vpar(2)
            repeat
          end
        else
          x = obx
          z = 59 + stem                 /* music font
          if passsize = CUESIZE
            z += 128                    /* music font
          end

   Connect notes of chord

          if c1 <> c2
            if stem = UP
              y = ts(c2,STAFFLOC)
              kscrdat = ""
              loop while y > ts(c1,STAFFLOC)
                perform subj
                y -= vpar(4)
              repeat
            else
              y = ts(c1,STAFFLOC)
              kscrdat = ""
              loop while y < ts(c2,STAFFLOC)
                perform subj
                y += vpar(4)
              repeat
            end
          end
          y = ts(c3,STAFFLOC)
          if ntype > EIGHTH

   Quarter notes and larger

            if ts(c1,BEAM_FLAG) = NO_BEAM

              t3 = y / vpar(1) + 2
              c16 = y + vpar20 * 2 + 1 / vpar(2) - 20
              t3 = c16 + 2

              if stem = UP
                if t11 = 0
                  t2 = 8
                  if t3 <= 0
                    t2 = t3 - 3
                  else
                    if t3 < 7
                      t2 = t3 - 4
                    else
                      if t3 < 13
                        t2 = t3 - 5
                      end
                    end
                    if passsize = CUESIZE
                      ++t2
                    end
                  end
                  t2 *= vpar(1)
                  t2 = t2 + 20 * vpar(2) / 2 - vpar20

                else
                  t13 = y / notesize
                  t14 = rem
                  if t14 = 0
                    t15 = 3                       /* tricky code
                  else
                    t15 = 2
                  end
                  t2 = y - vpar(t15) - vpar(79)
                  loop for t13 = t15 to t11
                    t2 -= vpar(2)
                  repeat
                  t12 = vpar(77) + vpar(6)
                  if t2 > t12
                    t2 = t12
                  end
                  if t14 <> 0 and t11 = 1
                    t14 = y
                    y = t2 - vpar(80)
                    kscrdat = ""
                    perform subj
                    y = t14
                  end
                end

           Raise bottom of stem if percussion note head  02/19/06

                t13 = ts(c1,SUBFLAG_1) & 0xf00000
                if t13 > 0
                  t13 >>= 20
                  if t13 = 1
                    y -= (vpar(1) - 1)
                  end
                end

                kscrdat = ""
                loop while y > t2
                  perform subj
                  y -= vpar(4)
                repeat
                y = t2
                perform subj
                if t11 > 0
                  y -= vpar(81)
                  if ts(c1,TUPLE) > 0
                    t13 = ts(c1,TUPLE)

             New 11/05/05  Convert tuple to 1000 * n1 + n2

                    t13 = ts(c1,TUPLE) & 0xffff
                    t14 = t13 >> 8
                    t13 &= 0xff
                    t14 *= 1000
                    t13 += t14

                    t14 = x + hpar(102)
                    t15 = y - vpar(82)
                    perform typeset_tuple (t13,t14,t15)
                  end
                  z = 125                       /* music font (repeater quarters)
                  kscrdat = ""
                  loop for t2 = 1 to t11
                    perform subj
                    y += vpar(2)
                  repeat
                end
              else
                if t11 = 0
                  t2 = 0
                  if t3 > 11
                    t2 = t3 - 1
                  else
                    if t3 > 6
                      t2 = t3
                    else
                      if t3 >= 0
                        t2 = t3 + 1
                      end
                    end
                    if passsize = CUESIZE
                      --t2
                    end
                  end
                  t2 = t2 * notesize / 2
                else
                  t13 = y / notesize
                  t14 = rem
                  if t14 = 0
                    t15 = 3                       /* tricky code
                  else
                    t15 = 2
                  end
                  t2 = y + vpar(t15) + vpar(79)
                  loop for t13 = t15 to t11
                    t2 += vpar(2)
                  repeat
                  t12 = vpar(78) - vpar(4)
                  if t2 < t12
                    t2 = t12
                  end
                  if t14 <> 0 and t11 = 1
                    t14 = y
                    y = t2 + vpar(80)
                    kscrdat = ""
                    perform subj
                    y = t14
                  end
                end

      Adding code (12/10/03) to decrease down stem for music with text for notes
        where note is on middle line of staff or one step above that.

                t15 = ts(c3,TEXT_INDEX)
                if t15 > 0
                  temp = trm(tsdata(t15))
                  if temp <> ""
                    t13 = ts(c3,STAFFLOC)
                    t14 = notesize << 1
                    t15 = notesize + 1
                    if t13 <= t14 and t13 > t15
                      t2 -= (notesize >> 1)
                    end
                  end
                end



           Lower top of stem if percussion note head  02/19/06

                t13 = ts(c1,SUBFLAG_1) & 0xf00000
                if t13 > 0
                  t13 >>= 20
                  if t13 = 1
                    y += (vpar(1) - 1)
                  end
                end

                kscrdat = ""
                loop while y < t2
                  perform subj
                  y += vpar(4)
                repeat
                y = t2
                perform subj
                if t11 > 0
                  if ts(c1,TUPLE) > 0
                    t13 = ts(c1,TUPLE)

             New 11/05/05  Convert tuple to 1000 * n1 + n2

                    t13 = ts(c1,TUPLE) & 0xffff
                    t14 = t13 >> 8
                    t13 &= 0xff
                    t14 *= 1000
                    t13 += t14

                    t14 = x + hpar(103)
                    t15 = ts(c1,STAFFLOC) - vpar(82)
                    perform typeset_tuple (t13,t14,t15)
                  end
                  y += vpar(81)
                  z = 125                       /* music font (repeater quarters)
                  x -= hpar(101)
                  kscrdat = ""
                  loop for t2 = 1 to t11
                    perform subj
                    y -= vpar(2)
                  repeat
                  x += hpar(101)
                end
              end
            else
*   2) Beams
              if ts(c1,BEAM_FLAG) = START_BEAM
                bcount = 1
                ++snum
                beampar(passtype,passnum,BM_SNUM) = snum
                if bit(4,super_flag) = 1
                  beampar(passtype,passnum,BM_TUPLE) = 1 + stem
                end
                beampar(passtype,passnum,BM_STEM) = stem
                beampar(passtype,passnum,BM_SIZE) = passsize

                t2 = ts(c1,TSR_POINT)               /* New code 05/14/03
                t3 = 28                             /* 28 = code for beam suggestion
                ++t3
                t3 <<= 2                            /* 116
                py = ors(tsr(t2){t3-2})
                t4 = 0
                if py > 0
                  py = py - 128
                  if py > 0
                    t4 = INT100 * py
                  else
                    py = 0 - py
                    t4 = INT100 * INT100 * py
                  end
                end
                beampar(passtype,passnum,BM_SUGG) = t4   /* End new code 05/14/03

              else
                bcount = beampar(passtype,passnum,BM_CNT) + 1
                beampar(passtype,passnum,BM_STEM) <<= 1
                beampar(passtype,passnum,BM_STEM) += stem
                if passsize < beampar(passtype,passnum,BM_SIZE)
                  beampar(passtype,passnum,BM_SIZE) = passsize
                end
              end
              beamdata(passtype,passnum,bcount) = ts(c1,BEAM_CODE)
              beampar(passtype,passnum,BM_CNT) = bcount
              if ts(c1,BEAM_FLAG) = END_BEAM
                beampar(passtype,passnum,BM_READY) = bcount
              end
            end
          else

   Eighth notes or smaller

            if ts(c1,BEAM_FLAG) = NO_BEAM
*   1) Flags
              if passtype = GRACE and ntype = SLASH8
                if stem = UP
                  z = 179                   /* music font
                else
                  z = 180                   /* music font
                end
                y = ts(c3,STAFFLOC)
                kscrdat = ""
                perform subj
              else
                if stem = UP
                  if ntype = EIGHTH
                    t3 = 53                 /* music font (eighth flag)
                    if y <= vpar(4) and passtype = REG and t11 = 0
                      t3 = 51             /* music font (shortened eighth flag)
                    end
                    t2 = 10 * notesize / 2
                  else
                    t3 = 55                 /* music font (sixteenth flag)
                    t2 = 0 - ntype * 2 + 20 * notesize / 2
                  end
                  z = 59                    /* music font (standard up stem)
                  t4 = notesize
                  t5 = 57                   /* music font (extra flag: 32nds, etc)
                  if passsize = CUESIZE
                    t2 -= vpar(1)
                    t3 += 128               /* music font
                    z += 128                /* music font
                    t4 = vpar(36)
                    t5 += 128               /* music font
                  end
                  kscrdat = ""
                  loop while y > t2
                    perform subj
                    y -= vpar(4)
                  repeat
                  t2 += vpar(1)
                  c16 = t2 * 2 / vpar(2)
                  if rem <> 0
                    ++t2
                  end
                  t2 += vpar(1)

                  y = ts(c3,STAFFLOC)
                  if t11 = 0                /* no repeaters
                    z = t3                  /* music font (flag character)
                    if y > t2
                      y = t2
                    end
                    kscrdat = ""
                    perform subj
                    if ntype < 5
                      z = t5                  /* music font (extra flag)
                      loop for t3 = 1 to 5-ntype
                        y -= t4
                        perform subj
                      repeat
                    end
                  else
                    t12 = y / notesize
                    t2 += t11 - 1 * notesize
                    if y > t2 or rem <> 0       /* note on space
                      t13 = t11 - 1 * notesize + vpar(67)
                      t14 = vpar(69)
                    else                        /* note on line
                      t13 = t11 - 1 * notesize + vpar(68)
                      t14 = vpar(70)
                    end

        t13 = amount to "lengthen" stem
        t14 = location of first repeater

                    if y > t2
                      y = t2
                    end
                    t15 = y
                    kscrdat = ""
                    loop
                      perform subj
                      y -= vpar(4)
                    repeat while y > t15 - t13
                    y = t15 - t13
                    z = t3
                    perform subj
                    if ntype < 5
                      z = t5                  /* music font (extra flag)
                      loop for t3 = 1 to 5-ntype
                        y -= t4
                        perform subj
                      repeat
                    end
                    y = t15 - t14
                    z = 126                   /* music font (repeater for eights)
                    x = x - hpar(99)
                    loop for t12 = 1 to t11
                      perform subj
                      y -= notesize
                    repeat
                    x = x + hpar(99)
                    if ts(c1,TUPLE) > 0
                      t13 = ts(c1,TUPLE)

               New 11/05/05  Convert tuple to 1000 * n1 + n2

                      t13 = ts(c1,TUPLE) & 0xffff
                      t14 = t13 >> 8
                      t13 &= 0xff
                      t14 *= 1000
                      t13 += t14

                      t14 = x + hpar(102)
                      t15 = y - vpar(83)
                      perform typeset_tuple (t13,t14,t15)
                    end
                  end
                else
                  if ntype = EIGHTH
                    t3 = 54                 /* music font (eighth flag)
                    if y >= vpar(5) and passtype = REG and t11 = 0
                      t3 = 52               /* music font (shortened eighth flag)
                    end
                    t2 = 0 - 2 * notesize / 2
                  else
                    t3 = 56                 /* music font (sixteenth flag)
                    t2 = 2 * ntype - 12 * notesize / 2
                  end
                  z = 60                    /* music font (standard down stem)
                  t4 = notesize
                  t5 = 58                   /* music font (extra flag)
                  if passsize = CUESIZE
                    t2 += vpar(1)
                    t3 += 128               /* music font
                    z += 128                /* music font
                    t4 = vpar(36)
                    t5 += 128               /* music font
                  end
                  kscrdat = ""
                  loop while y < t2
                    perform subj
                    y += vpar(4)
                  repeat
                  t2 -= vpar(1)
                  t2 -= vpar(1)
                  c16 = t2 * 2 / vpar(2)
                  if rem <> 0
                    --t2
                  end

                  y = ts(c3,STAFFLOC)
                  if t11 = 0
                    z = t3                    /* music font (flag character)
                    if y < t2
                      y = t2
                    end
                    kscrdat = ""
                    perform subj
                    if ntype < 5
                      z = t5                  /* music font
                      loop for t3 = 1 to 5-ntype
                        y += t4
                        perform subj
                      repeat
                    end
                  else
                    t12 = y / notesize
                    t2 -= t11 - 1 * notesize
                    if y < t2 or rem <> 0     /* note on space
                      if t11 = 2
                        t13 = notesize - vpar(71)
                      else
                        t13 = t11 - 1 * notesize - vpar(72)
                      end
                      t14 = vpar(75)
                    else                      /* note on line
                      if t11 = 2
                        t13 = notesize - vpar(73)
                      else
                        t13 = t11 - 1 * notesize - vpar(74)
                      end
                      t14 = vpar(76)
                    end

        t13 = amount to "lengthen" stem
        t14 = location of first repeater

                    if y < t2
                      y = t2
                    end
                    t15 = y
                    kscrdat = ""
                    loop
                      perform subj
                      y += vpar(4)
                    repeat while y < t15 + t13
                    y = t15 + t13
                    z = t3
                    perform subj
                    if ntype < 5
                      z = t5                  /* music font (extra flag)
                      loop for t3 = 1 to 5-ntype
                        y += t4
                        perform subj
                      repeat
                    end
                    y = t15 + t14
                    z = 126                   /* music font (repeater for eights)
                    x = x - hpar(100)
                    loop for t12 = 1 to t11
                      perform subj
                      y += notesize
                    repeat
                    x = x + hpar(100)
                    if ts(c1,TUPLE) > 0
                      t13 = ts(c1,TUPLE)

               New 11/05/05  Convert tuple to 1000 * n1 + n2

                      t13 = ts(c1,TUPLE) & 0xffff
                      t14 = t13 >> 8
                      t13 &= 0xff
                      t14 *= 1000
                      t13 += t14

                      t14 = x + hpar(103)
                      t15 = ts(c1,STAFFLOC) - vpar(82)
                      perform typeset_tuple (t13,t14,t15)
                    end
                  end
                end
              end
            else
*   2) Beams
              if ts(c1,BEAM_FLAG) = START_BEAM
                bcount = 1
                ++snum
                beampar(passtype,passnum,BM_SNUM) = snum
                if bit(4,super_flag) = 1
                  beampar(passtype,passnum,BM_TUPLE) = 1 + stem
                end
                beampar(passtype,passnum,BM_STEM) = stem
                beampar(passtype,passnum,BM_SIZE) = passsize

                t2 = ts(c1,TSR_POINT)               /* New code 05/14/03
                t3 = 28                             /* 28 = code for beam suggestion
                ++t3
                t3 <<= 2                            /* 116
                py = ors(tsr(t2){t3-2})
                t4 = 0
                if py > 0
                  py = py - 128
                  if py > 0
                    t4 = INT100 * py
                  else
                    py = 0 - py
                    t4 = INT100 * INT100 * py
                  end
                end
                beampar(passtype,passnum,BM_SUGG) = t4   /* End new code 05/14/03

              else
                bcount = beampar(passtype,passnum,BM_CNT) + 1
                beampar(passtype,passnum,BM_STEM) <<= 1
                beampar(passtype,passnum,BM_STEM) += stem
                if passsize < beampar(passtype,passnum,BM_SIZE)
                  beampar(passtype,passnum,BM_SIZE) = passsize
                end
              end
              beamdata(passtype,passnum,bcount) = ts(c1,BEAM_CODE)
              beampar(passtype,passnum,BM_CNT) = bcount
              if ts(c1,BEAM_FLAG) = END_BEAM
                beampar(passtype,passnum,BM_READY) = bcount
              end
            end
          end
        end
      return

 ┌───────────────────────────────────────────────────────────────┐
 │P  4. setax                                                    │
 │                                                               │
 │    Purpose:  Set accidental                                   │
 │                                                               │
 │    Inputs:  c3 = index into ts array                          │
 │             c4 = accident flag                                │
 │       passsize = note size (full, cue-size)                   │
 │            obx = x co-ordinate of object                      │
 │            oby = y co-ordinate of object                      │
 │              y = y co-ordinate of note head                   │
 │                                                               │
 │    Internal: x,y,z sent to subj                               │
 │                                                               │
 │                                                               │
 └───────────────────────────────────────────────────────────────┘

      procedure setax
        int t1,t2,t3,t4
                                          /* 02/25/97 shift changed from 4 to 8
        t2 = c4 >> 8                      /* x-offset (to the left)
        t1 = c4 & 0x0f                    /* accidental only

        t4 = 19                           /* New code 05/02/03   accidentals code = 19
        perform getpxpy (t4,c3)

        if pxx = 1
          x = obx + px
        else
          x = obx - t2 + px
        end
                                                /* end New code
        if bit(2,t1) = 1                  /* case: flat-flat or natural-(flat/sharp)
          z = bit(3,t1) + 64              /* flat or natural
          t2 = hpar(40)
          if passsize = CUESIZE
            z += 128                      /* cue size
            t2 = t2 * 8 / 10
          end
          kscrdat = ""
          perform subj
          x += t2
        end
        if t1 & 0x03 = 2
          if bit(3,t1) = 1
            z = 66                        /* double sharp
          else
            z = 63                        /* regular sharp
          end
        else
          z = bit(1,t1) + 64              /* flat or natural
        end
        if passsize = CUESIZE
          z += 128                        /* cue size
        end
        kscrdat = ""
        if bit(4,c4) = 0
          perform subj
        else
          perform subj2                   /* Addition to Code 02/25/97
        end
      return

 ┌───────────────────────────────────────────────────────────────────┐
 │P  5. superfor (operates on an entire chord at once)               │
 │                                                                   │
 │    Purpose:  Get new snums for forward tie, forward slurs and     │
 │                forward tuplet                                     │
 │                                                                   │
 │    Inputs:      c1 = pointer to top of chord                      │
 │                 c2 = pointer to bottom of chord                   │
 │           passtype = type of pass (reg,cue,grace,cuegrace)        │
 │            passnum = pass number                                  │
 │                  x = x co-ordinate of object                      │
 │                  y = y co-ordinate of object                      │
 │         super_flag = composite of SUPER_FLAGs for this chord      │
 │          slur_flag = composite of SLUR_FLAGs for this chord       │
 │               stem = stem direction                               │
 │                                                                   │
 │    Function: If there is a forward tie, this procedure increments │
 │              snum and puts result in tv4().  If there are         │
 │              forward slurs, this procedure increments snum and    │
 │              stores results in the appropriate                    │
 │              slurar(.,SL_NEXTSNUM).  If there is a forward        │
 │              tuplet, this procedure increments snum and           │
 │              constructs the tuar for this tuplet.  For all        │
 │              cases, the procedure increments supcnt and adds      │
 │              the new super-object number to supnums(.) for later  │
 │              output in the object record.                         │
 └───────────────────────────────────────────────────────────────────┘

      procedure superfor
        int t1,t2
        tiecnt = 0
        loop for c3 = c1 to c2
          if bit(0,ts(c3,SUPER_FLAG)) = 1      /* if tie starts
            ++snum
            ++supcnt
            supnums(supcnt) = snum
            ++tiecnt
            tv4(tiecnt) = snum
          end
        repeat
        loop for t1 = 1 to 8
          t2 = t1 * 2 - 2
          if t1 > 4
            t2 += 8
          end
          if bit(t2,slur_flag) = 1             /* if slur starts
            ++snum
            ++supcnt
            supnums(supcnt) = snum
            slurar(t1,SL_NEXTSNUM) = snum
          else
            slurar(t1,SL_NEXTSNUM) = 0
          end
        repeat
        if bit(4,super_flag) = 1
          ++snum
          ++supcnt
          supnums(supcnt) = snum
          tuar(passtype,passnum,TU_SNUM) = snum
          tuar(passtype,passnum,TU_Y1) = y
          if stem = UP
            tuar(passtype,passnum,TU_Y2) = y
          else
            tuar(passtype,passnum,TU_Y2) = ts(c1,STAFFLOC)
          end
          tuar(passtype,passnum,TU_FSTEM) = stem
          t1 = super_flag & 0x3c0                 /* bits 6,7,8,9 03-21-97
          t1 <<= 2
          tuar(passtype,passnum,TU_FSTEM) |= t1   /* tuplet flags 03-21-97
        end
      return

 ┌──────────────────────────────────────────────────────────────────┐
 │P  6. setart (operates on an entire chord at once)                │
 │                                                                  │
 │    Purpose:  create sub-objects for dots, spiccato and legato.   │
 │                                                                  │
 │    Inputs:  obx = x-position of object                           │
 │             oby = y-position of object                           │
 │              c1 = pointer to top note of chord                   │
 │              c2 = pointer to bottom note of chord                │
 │            stem = stem direction (UP or DOWN)                    │
 │                                                                  │
 │    Outputs:  Program may modify virtual endpoints in the ts      │
 │                array.                                            │
 │                                                                  │
 │    Operation:  There are two rules that can be followed          │
 │             Rule 1: (chord = single note, or dot on middle note  │
 │                         of chord, or more than one dot)          │
 │               If there is a slur, and slur starts (ends) near    │
 │                   the dot, put dot under (over) slur;            │
 │                 otherwise, if multi-track > 0, put dot on stem;  │
 │                   otherwise put dot on note head.                │
 │                                                                  │
 │             Rule 2: (all other situations)                       │
 │               If dot on note at stem end, put dot on stem;       │
 │                 otherwise, put dot at head end of chord.         │
 │                                                                  │
 │             If there is a slur into or out of this chord, then   │
 │             information on the placement of dot/legato or        │
 │             spiccato has already been compiled and is stored     │
 │             in the SLUR_X ROW element.  Otherwise, the place-    │
 │             ment needs to be computed here.                      │
 │                                                                  │
 │             Virtual endpoints are modified in all cases.         │
 │                                                                  │
 └──────────────────────────────────────────────────────────────────┘

      procedure setart
        int t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13
        int dot_xshift                                      /* New 05/14/05

        t2 = 0
        t9 = 0
        loop for t1 = c1 to c2
          t10 = ts(t1,SUBFLAG_2) & 0x3c    /* 05/17/03 Editorial arts not yet supported
          if t10 > 0
            ++t2
            t3 = t1
            t9 |= t10                 /* composite flag for chord
          end

      Using grace dot to typeset editorial staccato 02/06/04

          t10 = ts(t1,ED_SUBFLAG_2) & 0x0c      /* editorial staccato & spiccato
          if t10 > 0
            t10 <<= 8                           /* put this in higher order byte
            ++t2
            t3 = t1
            t9 |= t10
          end

        repeat
        if t2 = 0
          return
        end

    Step 1: determine starting position for dot/legatos or spiccatos

        t13 = 0       /* 03/24/97  potential modification to x position of articulation

        if c1 = c2 or (t3 <> c1 and t3 <> c2) or t2 > 1   /* follow rule 1
          t4 = ts(c1,SLUR_X)
          if t4 > 0 and ts(t4,6) > 0     /* there is a slur effecting dot
            y = ts(t4,5)
            t5 = ts(t4,6)             /* above/below flag
            t8 = 0                    /* no adjustment to virtual end points
          else
            t10 = ts(c1,MULTI_TRACK) >> 2
            if t10 > 0                      /* CHANGED from = 3  on 03/24/97
              if ts(c1,PASSNUM) = 1 and stem = DOWN
                t10 = 0
              end
              if ts(c1,PASSNUM) = 2 and stem = UP
                t10 = 0
              end
            end

      Code added 03/24/97 to check for print suggestions for articulations

            t12 = 1                        /* articulation code = 1
            if t9 & 0x04 > 0               /* spiccato code = 2         05/02/03
              ++t12
            end

            perform getpxpy (t12,c1)
            if pcontrol & 0x03 = 0x03      /* major location change flag
              if bit(2,pcontrol) = 1       /* place below
                t5 = BELOW
                if stem = UP
                  y = ts(c1,VIRT_NOTE)
                  t8 = notesize
                else
                  y = ts(c1,VIRT_STEM)
                  t8 = vpar(1)
                  if ts(c1,BEAM_FLAG) > NO_BEAM
                    t8 = vpar(2)
                  end
                end
              else
                t5 = ABOVE
                if stem = UP
                  y = ts(c1,VIRT_STEM)
                  t8 = vpar(1)
                  if ts(c1,BEAM_FLAG) > NO_BEAM
                    t8 = vpar(2)
                  end
                else
                  y = ts(c1,VIRT_NOTE)
                  t8 = notesize
                end
              end
            else

      End of 03/24/97 addition

              if t10 > 0
                y = ts(c1,VIRT_STEM)
                if stem = UP
                  t5 = ABOVE
                else
                  t5 = BELOW
                end
                t8 = vpar(1)
                if ts(c1,BEAM_FLAG) > NO_BEAM
                  t8 = vpar(2)
                end
              else
                y = ts(c1,VIRT_NOTE)
                if stem = UP
                  t5 = BELOW
                else
                  t5 = ABOVE
                end
                t8 = notesize
              end

       New 11/10/07   We need some code here which disables the interference section
                      below when there is a y-position modifier,

              if pcontrol & 0x01 > 0
                if (py = 0 and pyy = 0) or pyy = 1
                  t8 = 0
                end
              end

            end

            if pyy > 0
              y = py
            else
              y += py
            end
            t13 = px

          end
        else                                              /* follow rule 2

      Code added 03/24/97 to check for print suggestions for articulations

          t12 = 1                        /* articulation code = 1
          if t9 & 0x04 > 0               /* spiccato code = 2         05/02/03
            ++t12
          end

          perform getpxpy (t12,c1)
          if pcontrol & 0x03 = 0x03      /* major location change flag
            if bit(2,pcontrol) = 1       /* place below
              t5 = BELOW
              if stem = UP
                y = ts(c1,VIRT_NOTE)
                t8 = notesize
              else
                y = ts(c1,VIRT_STEM)
                t8 = vpar(1)
              end
            else
              t5 = ABOVE
              if stem = UP
                y = ts(c1,VIRT_STEM)
                t8 = vpar(1)
              else
                y = ts(c1,VIRT_NOTE)
                t8 = notesize
              end
            end
          else

      End of 03/24/97 addition

            if stem = UP
              if t3 = c1                                    /* top note
                t5 = ABOVE
                y = ts(c1,VIRT_STEM)
                t8 = vpar(1)
              else
                t5 = BELOW
                y = ts(c1,VIRT_NOTE)
                t8 = notesize
              end
            else
              if t3 = c1                                    /* top note
                t5 = ABOVE
                y = ts(c1,VIRT_NOTE)
                t8 = notesize
              else
                t5 = BELOW
                y = ts(c1,VIRT_STEM)
                t8 = vpar(1)
              end
            end

       New 11/10/07   We need some code here which disables the interference section
                      below when there is a y-position modifier,

            if pcontrol & 0x01 > 0
              if (py = 0 and pyy = 0) or pyy = 1
                t8 = 0
              end
            end

          end

          if pyy > 0
            y = py
          else
            y += py
          end
          t13 = px

        end

      New (05/14/05) code to set value of dot_xshift for staccato over (under) stem

        dot_xshift = 0
        if t5 = ABOVE
          if stem = UP
            dot_xshift = hpar(19)
            if ts(c1,BEAM_FLAG) <= NO_BEAM
              y -= vpar(1)
            end
          end
        else
          if stem = DOWN
            dot_xshift = 0 - hpar(19)
            if ts(c1,BEAM_FLAG) <= NO_BEAM
              y += vpar(1)
            end
          end
        end



      check for interference in cases where y is based on VIRT_

        if t8 <> 0
          if (stem = DOWN and t5 = ABOVE) or (stem = UP and t5 = BELOW)
            t11 = HEAD
          else
            t11 = TAIL
          end
          if t9 & 0x04 > 0                         /* spiccato is special case
          if (t9 & 0x04 > 0) or (t9 & 0x400 > 0)     /* spiccato is special case (02/06/04)
            if stem = DOWN
              if t5 = ABOVE         /* note
                if y > vpar(1)
                  y = vpar(1)
                end
                y -= 5 * notesize / 4
              else
                if y < vpar(8)
                  y = vpar(8)
                end
                y += vpar(1) + vpar(50)      /* OK 4-22-95
              end
            else                /* UP
              if t5 = ABOVE
                if y > 0
                  y = 0
                end
                y -= vpar(1)
                y -= vpar(1)
                c16 = y * 2 / vpar(2)
                if rem <> 0
                  --y
                end

              else                  /* note
                if y < vpar(7)
                  y = vpar(7)
                end
                y += 5 * notesize / 4 + vpar(50)
              end
            end
          else
            t6 = 1
            if t5 = ABOVE
              y -= t8
              if y >= 0
                t6 = y / notesize
                t6 = rem
              else
                y = 0 - notesize / 4 + y
              end
              t7 = -1
            else
              y += t8
              if y <= vpar(8)
                t6 = y / notesize
                t6 = rem
              else
                y = notesize / 4 + y
              end
              t7 = 1
            end

      adjust for interference with staff

            if t6 = 0
              y = vpar(1) * t7 + y
              c16 = t7 + 20 * vpar(2) / 2 - vpar20
              y += c16

            end
          end
        end

    Step 2: write out articulations



     Code addition 01/06/06: If art_flag = 48, then please set all staccatos and/or
                             legatos above the note and above the staff lines.

        if art_flag = 48
          if t9 & 0x38 > 0
            if y > (0 - vpar(1))
              y = 0 - vpar(1)
            end
          end
        end

        x = obx + t13
        kscrdat = ""
        if t9 & 0x18 > 0                  /* staccato
          z = 96                          /* music font
          x += dot_xshift                 /* New 05/14/05
          perform subj
          x -= dot_xshift                 /* New 05/14/05
          y = notesize * t7 + y
        end
        if t9 & 0x30 > 0                  /* legato
          z = 99                          /* music font
          x += dot_xshift                 /* New 05/14/05
          perform subj
          x -= dot_xshift                 /* New 05/14/05
          y = notesize * t7 + y
        end

    Using grace dot to typeset editorial staccato 02/06/04

        if t9 & 0x800 > 0
          z = 172                         /* grace dot used as editorial staccato
          x += vpar(1) / 2
          x += dot_xshift / 2             /* New 05/14/05 and 09/22/05
          kscrdat = ""
          perform subj
          x -= dot_xshift / 2             /* New 05/14/05 and 09/22/05
          x -= vpar(1) / 2
          y = notesize * t7 + y
        end

    Using ordinary spiccato for the moment to typeset editorial spiccato 02/06/04

        if t9 & 0x400 > 0                 /* spiccato
          z = 98                          /* music font
          if t5 = ABOVE
            --z                           /* music font
          end
          x += dot_xshift                 /* New 05/14/05

       Code added 05/26/05 to implement arbitrary placement of editorial spiccatos

          kscrdat = ""
          if bit(2,art_flag) = 1
            t13 = y
            if stem = UP
              y = oby + vpar(4)
            else
              y = oby - (vpar(5) / 2)
            end
            perform subj
            y = t13
          else
            perform subj
          end

          x -= dot_xshift                 /* New 05/14/05
          if t5 = BELOW
            y -= vpar(50)
          end
          if y >= 0
            y = y * 2 + 1 / vpar(2)
          else
            y = y * 2 - 1 / vpar(2)
          end
          y = y * vpar(2) / 2
        else

          if t9 & 0x04 > 0                /* spiccato
            z = 98                        /* music font
            if t5 = ABOVE
              --z                         /* music font
            end
            x += dot_xshift               /* New 05/14/05

       Code added 05/26/05 to implement arbitrary placement of spiccatos

            kscrdat = ""
            if bit(2,art_flag) = 1
              t13 = y
              if stem = UP
                y = oby + vpar(4)
              else
                y = oby - (vpar(5) / 2)
              end
              perform subj
              y = t13
            else
              perform subj
            end

            x -= dot_xshift               /* New 05/14/05
            if t5 = BELOW
              y -= vpar(50)
            end
            y = y / vpar(1) * vpar(1)
            if y >= 0
              y = y * 2 + 1 / vpar(2)
            else
              y = y * 2 - 1 / vpar(2)
            end
            y = y * vpar(2) / 2

          else
            y -= notesize * t7
          end
        end

    Step 3: adjust virtual end points

        if t8 <> 0
          if t11 = HEAD
            loop for t8 = c1 to c2
              ts(t8,VIRT_NOTE) = y
            repeat
          else
            loop for t8 = c1 to c2
              ts(t8,VIRT_STEM) = y
            repeat
          end
        end
      return

 ┌────────────────────────────────────────────────────────────────────┐
 │P  7. setperf (operates on an entire chord at once)                 │
 │                                                                    │
 │    Purpose:  create sub-objects for turns, trills, shakes,         │
 │              mordents, horizontal accents, thumb positions,        │
 │              open string, numbers, harmonics, down-bows,           │
 │              up-bows, fermatas. (and tremulos as of 01/07/06)      │
 │                                                                    │
 │    Inputs:    obx = x-position of object                           │
 │               oby = y-position of object                           │
 │                c1 = pointer to top of chord                        │
 │                c2 = pointer bottom of chord                        │
 │                c4 = virtual vertical position of controlling       │
 │                         note head                                  │
 │                c5 = virtual vertical position of end of stem       │
 │                c8 = slur present flag                              │
 │                                     0 = not present (usually)      │
 │                                     1 = present at head            │
 │                                     2 = present at stem            │
 │              stem = stem direction  0 = up                         │
 │                                     1 = down                       │
 │        super_flag = composite of SUPER_FLAGs for this chord        │
 │                                                                    │
 │    Operation:  If multi-track > 0, put indications at the stem     │
 │                  end of the chord;                                 │
 │                else, put indications above the chord               │
 │                                                                    │
 │    Internal: c4,c5,c7,c9,c13 used to communicate with yadjust      │
 │                                                                    │
 04-08-97 Modification.                                          │
 │                                                                    │
 │    It turns out that for turns, trill, shakes, and mordents,       │
 │                 and tremulos, as of 01/07/06,                      │
 │    we want to allow multiple ornaments on a chord.  Therefore,     │
 │    these ornaments need to be processed individually, and not      │
 │    grouped, as are accents, numbers, up and down bows, fermatas,   │
 │    etc.                                                            │
 │                                                                    │
 │                                                                    │
 └────────────────────────────────────────────────────────────────────┘

      procedure setperf
        str temp.100                             /* 04/24/03
        bstr bs.600,bt.600
        int t1,t2,t3,t4,t5,t7,t8,t9,t10
        int ed_subflag_1,ed_subflag_2            /* New variables 05/17/03
        int merged_subflag_1,merged_subflag_2
        int lsqx,rsqx,sqy,glyph,sq_glyph

    1. Determine placement: c7 = situation flag: 0 = place on note head
                                                 1 = place on stem

        if ts(c1,MULTI_TRACK) >> 2 > 0
          c7 = 1
        else
          c7 = 1 - stem
        end

    2. Long trill

        if super_flag & 0x06 > 0          /* if begin ~~~~~
          subflag_1 = 0
          loop for t8 = c1 to c2            /* loop added 11/05/05 to accomodate all ornaments
            subflag_1 = subflag_1 | ts(t8,SUBFLAG_1)           /* on notes of a chord
          repeat

          t5 = ts(c1,PASSNUM)
          ++snum
          pre_tsnum(t5) = snum
          ++supcnt
          supnums(supcnt) = snum
          c13 = vpar(53)
          pre_ctrarrf(t5) = bit(2,super_flag)     /* tr. trill
          if pre_ctrarrf(t5) = 0
            c13 = vpar(51)
          end

          if pre_ctrarrf(t5) = 1         /* tr. present
            t3 = subflag_1 & 0x70 >> 4   /* t3 = 0 to 7 (05/17/03 editorial not supported yet)
            t3 = int("01312311"{t3+1})
            pre_ctrarrf(t5) += t3
            if subflag_1 & 0x80000 > 0   /* bit 19 is set 11/05/05
              pre_ctrarrf(t5) += 3       /* add 3 to R super-object parameter 4
            end
          end

          ++pre_ctrarrf(t5)
          perform yadjust
          pre_try(t5) = y - oby
                                  /* Code added 02/24/97
          t2 = 4                        /* ornament code = 4
          perform getpxpy (t2,c1)

          if pyy > 0
            pre_try(t5) = py
          else
            pre_try(t5) += py
          end
                                  /* End of 02/24/97 addition
        else

    3. Back ties (sub-objects)  New code 04/22/08

       Note: Back ties are handled like ornaments.  This means that a note with
             a back tie can have at most one ornament attached to it.  Limitation??

          sugg_flg2 = 0                     /* added    05/02/03 for ornaments, use also
                                            /*   with back ties

          loop for t8 = c1 to c2            /* loop accomodates back ties on all chord notes
            subflag_1 = ts(t8,SUBFLAG_1)
            t5 = subflag_1 & 0x03000000     /*  00000011 00000000 00000000 00000000
            if t5 > 0
              t2 = 4 + sugg_flg2            /* ornament code = 4
              if sugg_flg2 = 0              /* New code 05/02/03
                ++sugg_flg2
              end

              x = obx - vpar(4)
              t5 >>= 24
              if t5 = 1                     /* overhand back tie
                y = 0 - vpar(2)
                z = 2036                    /* overhand tie character
              else
                y = vpar(2)
                z = 2164                    /* underhand tie charachter
              end
              y += oby

              perform getpxpy (t2,t8)

              x += px
              if pyy > 0
                py -= y
                pyy = 0
              end
              y += py
              kscrdat = ""
#if AUTOSCR
#else
              perform subj                  /* this feature not implemented in autoscr yet
#endif
            end
          repeat

    4+5. Ornaments and their accidentals need to be handled together

       New code rewrite 05/17/03 to accommodate editorial ornaments and their accidentals

          loop for t8 = c1 to c2            /* loop added 04-08-97 to accomodate all ornaments
            subflag_1 = ts(t8,SUBFLAG_1)                       /* on notes of a chord
            subflag_2 = ts(t8,SUBFLAG_2)
            ed_subflag_1 = ts(t8,ED_SUBFLAG_1)
            ed_subflag_2 = ts(t8,ED_SUBFLAG_2)
            merged_subflag_1 = subflag_1 | ed_subflag_1
            merged_subflag_2 = subflag_2 | ed_subflag_2

            t5 = merged_subflag_1 & 0x0f             /* turn,tr,shake,mordent, etc.
            if t5 > 0 and t5 < 6                     /* 5 ornaments at the moment
            if t5 > 0 and t5 < 7                     /* 6 ornaments as of 01/07/06

       Raise (lower) turn, if slur and turn are present on note head

              if c7 = 0 and c8 = 1
                if t5 = 1                   /* turn
                  if stem = UP
                    c16 = c4 * 2 / vpar(2)
                    if rem <> 0
                      ++c4
                    end
                    c4 += vpar(1)
                  else
                    c4 -= vpar(1)
                    c16 = c4 * 2 / vpar(2)
                    if rem <> 0
                      --c4
                    end
                  end
                end
              end

      a. We must know definitively whether ornament goes above or below notes,
           and we must determine whether there is an "intervening" accidental.

              t7 = c7                       /* save c7
              t2 = 4 + sugg_flg2            /* ornament code = 4
              if sugg_flg2 = 0              /* New code 05/02/03
                ++sugg_flg2
              end
              perform getpxpy (t2,t8)

              if bit(0,pcontrol) = 1
                if bit(1,pcontrol) = 1
                  if bit(2,pcontrol) = 0
                    c7 = 1 - stem
                  else
                    c7 = stem
                  end
                end
              end
              t1 = c7 + stem                /* t1 = 1 means ornament goes above

              t2 = 0
              t3 = merged_subflag_1 & 0x3f0 >> 4
              t9 = ed_subflag_1 & 0x3f0 >> 4
              t10 = 0                       /* 0 will mean actual, as opposed to editorial
              if t3 > 0
                if t1 = 1
                  if t3 > 7                 /* ax under on ornament above
                    t2 = 1
                    if t9 > 7
                      t10 = 1               /* and this is editorial
                    end
                  end
                else
                  if t3 & 0x07 > 0          /* ax over on ornament below
                    t2 = 2
                    if t9 & 0x07 > 0
                      t10 = 1               /* and this is editorial
                    end
                  end
                end
              end
              if t2 > 0                     /* put accidental first
                if t2 = 1
                  t4 = t3 >> 3
                else
                  t4 = t3 & 0x07
                end
                c13 = vpar(56)
                perform yadjust
                if c9 <> 1
                  y -= vpar(1)
                  c16 = y * 2 / vpar(2)
                  if rem <> 0
                    --y
                  end
                end
                x = obx
                if t2 = 1 and (t5 = 1 or t5 = 5)
                  x += hpar(70)
                end
                x += px
                if pyy > 0
                  py -= y
                  pyy = 0
                end
                y += py
                kscrdat = ""

            Deal with case where ornament is real, but accidental is editorial

                if subflag_1 & 0x0f > 0 and t10 = 1
                  x -= hpar(124)
                  y -= vpar(86)
                  z = 244                         /* open square bracket
                  perform subj
                  x += hpar(124)
                  y += vpar(86)
                end

            Put out "first" accidental

                z = int("39389"{t4})              /* music font
                z += 210                          /* music font
                perform subj
                if t4 < 3
                  z = int("39"{t4})                 /* music font
                  x += hpar(z+67)                   /* hpar(70) or hpar(76)
                  z += 210                          /* music font
                  if t2 = 1 and (t5 = 1 or t5 = 5)
                    x += hpar(70)
                  end
                  perform subj
                end

            Deal with case where ornament is real, but accidental is editorial

                if subflag_1 & 0x0f > 0 and t10 = 1
                  x += hpar(125)
                  y -= vpar(86)
                  z = 245                         /* close square bracket
                  perform subj
                end
              end

      b. Now put out turn, tr., shake, mordent, delayed turn
            tremulo added 01/07/06 (primary only)

              t3 = t5
              if c3 = 5
                c3 = 1
              end
              c13 = 51 + t3
              c13 = vpar(c13)
                                    01/07/06 for tremulos
              if t3 = 6
                c13 = vpar(4)
              end

              perform yadjust
              if c9 <> 1
                y -= vpar(1)
                c16 = y * 2 / vpar(2)
                if rem <> 0
                  --y
                end
              end
              x = obx
              x += px
              if pyy > 0
                py -= y
                pyy = 0
              end
              y += py
              kscrdat = ""

            Deal with case where ornament is editorial

              if ed_subflag_1 & 0x0f > 0
                if t3 = 1 or t3 = 5          /* turn and delayed turn
                  lsqx  = hpar(126)
                  rsqx  = hpar(127)
                  sqy   = vpar(87)
                  glyph = 242                /* turn ornament
                  sq_glyph = 244             /* small square bracket
                else
                  if t3 = 2                  /* tr. trill

       Conditional code added 02/04/04 to implement Roman editorial trills

#if ROMAN_EDIT
                    y -= vpar(1)
                    ++sobcnt
                    sobx = x - obx
                    soby = y - oby
                    sobl(sobcnt) = "W " // chs(sobx) // " " // chs(soby) // " "
                    sobl(sobcnt) = sobl(sobcnt) // "31 tr"
                    goto SETP01

#else
                    lsqx  = hpar(122)
                    rsqx  = hpar(123)
                    sqy   = vpar(85)
                    glyph = 254              /* editorial trill ornament
                    sq_glyph = 195           /* cue square bracket
#endif
                  else
                    if t3 = 3                /* shake
                      lsqx  = hpar(128)
                      rsqx  = hpar(129)
                      sqy   = vpar(88)
                      glyph = 239            /* shake ornament
                      sq_glyph = 244         /* small square bracket
                    else                     /* mordant
                      lsqx  = hpar(130)
                      rsqx  = hpar(131)
                      sqy   = vpar(89)
                      glyph = 238            /* mordant ornament
                      sq_glyph = 244         /* small square bracket
                    end
                  end
                end
                x -= lsqx
                y -= sqy
                z = sq_glyph                      /* open square bracket
                perform subj
                x += lsqx
                y += sqy
                z = glyph
                perform subj
                x += rsqx
                y -= sqy
                z = sq_glyph + 1                  /* close square bracket
                perform subj
              else

            Deal with case where ornament is primary

            01/07/06  Adding code to deal with tremulo ornament (T)

                z = int("71437"{t3})       /* music font
                z += 235                   /* music font
                perform subj

                if t3 < 6
                  z = int("71437"{t3})       /* music font
                  z += 235                   /* music font
                  perform subj
                else
                  c16 = y
                  z = 127
                  perform subj
                  y -= vpar(3) / 2
                  perform subj
                  y -= vpar(3) / 2
                  perform subj
                  y = c16
                end
              end

      c. Put out remaining accidentals above or below notes.

SETP01:
                                          /* t1 = 1 means ornament goes above
              t2 = 0
              t3 = merged_subflag_1 & 0x3f0 >> 4
              t9 = ed_subflag_1 & 0x3f0 >> 4
              t10 = 0                       /* 0 will mean actual, as opposed to editorial
              if t3 > 0
                if t1 = 1
                  if t3 & 0x07 > 0          /* ax over on ornament above
                    t2 = 1
                    if t9 & 0x07 > 0
                      t10 = 1               /* and this is editorial
                    end
                  end
                else
                  if t3 > 7                 /* ax under on ornament below
                    t2 = 2
                    if t9 > 7
                      t10 = 1               /* and this is editorial
                    end
                  end
                end
              end
              if t2 > 0                     /* put accidental
                if t2 = 1
                  t4 = t3 & 0x07
                else
                  t4 = t3 >> 3
                end
                c13 = vpar(56)
                perform yadjust
                if c9 <> 1
                  y -= vpar(1)
                  c16 = y * 2 / vpar(2)
                  if rem <> 0
                    --y
                  end
                end
                x = obx
                if t2 = 2 and (t5 = 1 or t5 = 5)
                  x += hpar(70)
                end
                x += px
                if pyy > 0
                  py -= y
                  pyy = 0
                end
                y += py
                kscrdat = ""

            Deal with case where ornament is real, but accidental is editorial

                if subflag_1 & 0x0f > 0 and t10 = 1
                  x -= hpar(124)
                  y -= vpar(86)
                  z = 195                         /* open square bracket
                  perform subj
                  x += hpar(124)
                  y += vpar(86)
                end

            Put out "second" accidental

                z = int("39389"{t4})              /* music font
                z += 210                          /* music font
                perform subj
                if t4 < 3
                  z = int("39"{t4})                 /* music font
                  x += hpar(z+67)                   /* hpar(70) or hpar(76)
                  z += 210                          /* music font
                  if t2 = 2 and (t5 = 1 or t5 = 5)
                    x += hpar(70)
                  end
                  perform subj
                end

            Deal with case where ornament is real, but accidental is editorial

                if subflag_1 & 0x0f > 0 and t10 = 1
                  x += hpar(125)
                  y -= vpar(86)
                  z = 196                         /* close square bracket
                  perform subj
                end
              end
              c7 = t7                               /* restore "real" c7
            end
          repeat
        end

       End of code rewrite for editorial ornaments and their accidentals

    6. Construct composite subflag_1 and subflag_2, ed_subflag_1 and ed_subflag_2

       New code rewrite 05/17/03 to accommodate other editorial marks

        subflag_1 = ts(c1,SUBFLAG_1)
        subflag_2 = ts(c1,SUBFLAG_2)
        ed_subflag_1 = ts(c1,ED_SUBFLAG_1)
        ed_subflag_2 = ts(c1,ED_SUBFLAG_2)
        if c2 > c1
          t5 = ts(c1,TSR_POINT)
          bs = cbi(tsr(t5){5..68})                  /* 04/24/03  merge only subobj suggs.
          loop for t3 = c1+1 to c2
            subflag_1 |= ts(t3,SUBFLAG_1)
            subflag_2 |= ts(t3,SUBFLAG_2)
            ed_subflag_1 |= ts(t3,ED_SUBFLAG_1)
            ed_subflag_2 |= ts(t3,ED_SUBFLAG_2)
            t4 = ts(t3,TSR_POINT)
            bt = cbi(tsr(t4){5..68})                /* 04/24/03  merge only subobj suggs.
            bs = bor(bs,bt)
          repeat
          temp = cby(bs)
          t3 = TSR_LENG
          tsr(t5) = tsr(t5){1,4} // temp // tsr(t5){69..t3}    /* 05/02/03
        end
        merged_subflag_1 = subflag_1 | ed_subflag_1
        merged_subflag_2 = subflag_2 | ed_subflag_2

    7. Horizontal and vertical accents

        if merged_subflag_2 & 0x01c0 > 0

       Lower (raise) horizontal accent, if it and slur are present on note head

          if c7 = 0 and c8 = 1
            if bit(6,merged_subflag_2) = 1   /* horizontal accent
              if stem = UP
                c4 -= vpar(1)
                c16 = c4 * 2 / vpar(2)
                if rem <> 0
                  --c4
                end
              else
                c16 = c4 * 2 / vpar(2)
                if rem <> 0
                  ++c4
                end
                c4 += vpar(1)
              end
            end
          end
          t7 = c7
          t2 = 3                        /* accent code = 3
          perform getpxpy (t2,c1)

          if bit(0,pcontrol) = 1
            if bit(1,pcontrol) = 1
              if bit(2,pcontrol) = 0
                c7 = 1 - stem
              else
                c7 = stem
              end
            end
          end
          x = obx + px
          if bit(6,subflag_2) = 1
          if bit(6,merged_subflag_2) = 1    /* 01/26/08  Fixing a small bug
            c13 = vpar(57)
            glyph    = 93                   /* horizontal accent
            lsqx     = hpar(132)
            rsqx     = hpar(133)
            sqy      = vpar(90)
            sq_glyph = 195                  /* cue square bracket
          end
          if bit(7,subflag_2) = 1
          if bit(7,merged_subflag_2) = 1    /* 01/26/08  Fixing a small bug
            c13 = vpar(58)
            glyph = 94                      /* vertical accent--point up
            lsqx  = hpar(134)
            rsqx  = hpar(135)
            sqy   = vpar(91)
            sq_glyph = 244                  /* small square bracket
          end
          if bit(8,subflag_2) = 1
          if bit(8,merged_subflag_2) = 1    /* 01/26/08  Fixing a small bug
            c13 = vpar(58)
            glyph = 95                      /* vertical accent--point down
            lsqx  = hpar(134)
            rsqx  = hpar(135)
            sqy   = vpar(91)
            sq_glyph = 244                  /* small square bracket
          end
          perform yadjust
          if c9 <> 1
            y -= vpar(1)
            c16 = y * 2 / vpar(2)
            if rem <> 0
              --y
            end
          end
          if pyy > 0
            y = py
          else
            y += py
          end
          kscrdat = ""
          if ed_subflag_2 & 0x01c0 > 0
            x -= lsqx
            y -= sqy
            z = sq_glyph                          /* open square bracket
            perform subj
            x += lsqx
            y += sqy
          end
          z = glyph
          perform subj
          if ed_subflag_2 & 0x01c0 > 0
            x += rsqx
            y -= sqy
            z = sq_glyph + 1                      /* close square bracket
            perform subj
          end
          c7 = t7
        end

    8. harmonics

        if merged_subflag_2 & 0x0200 > 0
          t2 = 7                        /* harmonics code = 7
          perform getpxpy (t2,c1)

          x = obx + px
          z = 123                     /* music font
          c13 = vpar(59)
          t7 = c7
          if stem = 0
            c7 = 1
          else
            c7 = 0
          end
          perform yadjust             /* c9 set by yadjust
          c7 = t7
          if pyy > 0
            y = py
          else
            y += py
          end
          kscrdat = ""
          perform subj
        end

    9. thumb positions, open string

        c9 = merged_subflag_2 & 0x0c00
        if c9 > 0
          t2 = 8                        /* thumb-open code = 8
          perform getpxpy (t2,c1)

          x = obx + px
          if bit(10,merged_subflag_2) = 1
            z = 124                   /* music font
            c13 = vpar(60)
          else
            z = 199                   /* music font
            c13 = vpar(48)
          end
          t7 = c7
          if stem = 0
            c7 = 1
          else
            c7 = 0
          end
          perform yadjust             /* c9 set by yadjust
          c7 = t7
          if pyy > 0
            y = py
          else
            y += py
          end
          kscrdat = ""
          perform subj
        end

   10. fingerings (above staff for the moment)   Note: suggestions for fingerings
                                                 not yet implemented here.

        c9 = merged_subflag_2 >> 12
        if c9 > 0

     If above the staff, reverse the flags

          t4 = 0
VVV2:
          t1 = 0x0f
          t3 = 4
VVV1:
          t2 = c9 & t1
          if t2 > t1 >> 1
            t1 = t1 << 4 + t1
            t3 += 4
            goto VVV1
          end
          t4 <<= t3
          t4 += t2
          c9 >>= t3
          if c9 > 0
            goto VVV2
          end
          t5 = t4


VVV4:
          t1 = 0x0f
          t3 = 4
VVV3:
          t2 = t5 & t1
          if t2 > t1 >> 1
            t1 = t1 << 4 + t1
            t3 += 4
            goto VVV3
          end

      Typeset t2

          c13 = vpar(48)
          perform yadjust             /* c9 set by yadjust
          t4 = t3 - 1 >> 2 * (hpar(73) / 2)
          x = obx - t4
VVV5:
          t4 = t2 & 0x0f
          z = t4 & 0x07 + 199             /* music font
          kscrdat = ""
          perform subj
          if t4 > 7
            x += hpar(73)
            z = 220                       /* music font
            perform subj
            x += hpar(73)
            t2 >>= 4
            goto VVV5
          end

          t5 >>= t3
          if t5 > 0
            goto VVV4
          end
        end

   11. up-bows, down-bows

        if merged_subflag_2 & 0x03 > 0
          t2 = 6                        /* bowing code = 6
          perform getpxpy (t2,c1)

          x = obx + px
          if bit(0,merged_subflag_2) = 1
            c13 = vpar(61)
            z = 117                       /* music font
          else
            c13 = vpar(62)
            z = 116                       /* music font
          end
          t7 = c7
          if stem = 0
            c7 = 1
          else
            c7 = 0
          end
          perform yadjust
          c7 = t7
          if c9 <> 1
            y -= vpar(1)
            c16 = y * 2 / vpar(2)
            if rem <> 0
              --y
            end
          end
          if pyy > 0
            y = py
          else
            y += py
          end
          kscrdat = ""
          perform subj
        end

    12. fermatas

        if bit(14,merged_subflag_1) = 1
          t2 = 15                       /* upright fermata code = 15
          perform getpxpy (t2,c1)

          x = obx + px
          c13 = vpar(63)
          z = 101                         /* music font
          perform yadjust
          if pyy > 0
            y = py
          else
            y += py
          end
          kscrdat = ""
          perform subj
        end
        if bit(15,merged_subflag_1) = 1
          t2 = 16                       /* inverted fermata code = 16
          perform getpxpy (t2,c1)

          x = obx + px
          c13 = vpar(63)
          z = 102                         /* music font
          t7 = c7
          if stem = 0
            c7 = 0
          else
            c7 = 1
          end
          perform yadjust
          c7 = t7
          y -= vpar(63)
          if pyy > 0
            y = py
          else
            y += py
          end
          kscrdat = ""
          perform subj
        end
      return

 ┌────────────────────────────────────────────────────────────────────┐
 │P  9. yadjust (operates on an entire chord at once)                 │
 │                                                                    │
 │    Purpose:  to work in conjunction with setperf to adjust         │
 │              the y position so that the indication will            │
 │              fall on c4/c5 or above/below the staff line,          │
 │              whichever is higher/lower.  Procedure also            │
 │              determines a new value of the virtual endpoints,      │
 │              c4/c5 based on the y position and the vertical        │
 │              space parameter, c13, which is passed to the          │
 │              procedure.                                            │
 │                                                                    │
 │    Inputs:   c4 = virtual vertical position of controlling         │
 │                       note head                                    │
 │              c5 = virtual vertical position of end of stem         │
 │              stem = stem direction  0 = up                         │
 │                                     1 = down                       │
 │              c7 = situation flag    0 = place on note head         │
 │                                     1 = place on stem              │
 │             c13 = vertical space of next character to set          │
 │                                                                    │
 │    Outputs:  c4 = updated vertical position of controlling         │
 │                       note head                                    │
 │              c5 = updataed vertical position of end of stem        │
 │              c9 = position flag (1 = place on top of staff)        │
 │                                                                    │
 └────────────────────────────────────────────────────────────────────┘

      procedure yadjust
        int t1
        if c7 = 0
          if stem = DOWN
            if c4 > vpar(1)
              c4 = vpar(1)
            end
          else
            if c4 < vpar(7)
              c4 = vpar(7)
            end
          end
        else
          if stem = DOWN
            if c5 < vpar(8)
              c5 = vpar(8)
            end
          else
            if c5 > 0
              c5 = 0
            end
          end
        end
*   determine y location
        c9 = stem + c7
        t1 = 1
        if c9 = 1
          t1 = -1
        end
        if c7 = 0
          y = 5 * notesize / 4 * t1 + c4
          if stem = UP
            y += c13
          end
        else
          y = vpar(2) * t1 + c5        /* was vpar(1)
          if stem = DOWN
            y += c13
          end
        end
*    compute new vertual endpoints
        if c7 = 1
          c5 += c13 * t1
        else
          c4 += c13 * t1
        end
      return

 ┌────────────────────────────────────────────────────────┐
 │P 10. setleger                                          │
 │                                                        │
 │    Purpose, set leger lines for a chord (object)       │
 │                                                        │
 │    Inputs:  obx = x-position of object                 │
 │        passsize = note size (full, cue-size)           │
 │              c7 = pointer to lowest note in chord      │
 │              c8 = pointer to highest note in chord     │
 │              c9 = extra width of leger lines           │
 │            stem = stem direction   0 = up, 1 = down    │
 │                                                        │
 │    Internal: x,y,z  sent to subj                       │
 │                                                        │
 └────────────────────────────────────────────────────────┘

      procedure setleger
        z = passsize * 128 + 45                 /* music font
        x = obx
        if stem = UP
          ++x
        end
        if ts(c8,STAFFLOC) < 0
          y = 0 - notesize
          kscrdat = ""
          loop while y >= ts(c8,STAFFLOC)
            perform subj
            if c9 > 0
              x += c9
              perform subj
              x -= c9
            end
            y -= notesize
          repeat
        end
        if ts(c7,STAFFLOC) > vpar(9)
          y = vpar(10)
          kscrdat = ""
          loop while y <= ts(c7,STAFFLOC)
            perform subj
            if c9 > 0
              x += c9
              perform subj
              x -= c9
            end
            y += notesize
          repeat
        end
      return

 ┌──────────────────────────────────────────────────────────────────┐
 │P 11. wideleger                                                   │
 │                                                                  │
 │    Purpose: set wide a leger line for a note head located on,    │
 │                above, or below a leger line                      │
 │                                                                  │
 │    Inputs:  obx = x-position of object                           │
 │             oby = y-position of object                           │
 │               x = x-position of note head                        │
 │               y = y-position of note head                        │
 │        passsize = note size (full size, cue size)                │
 │             c10 = note-on-line flag:  0 = on line, 1 = on space  │
 │                                                                  │
 │    Internal:  x,y,z  sent to subj                                │
 │                                                                  │
 └──────────────────────────────────────────────────────────────────┘

      procedure wideleger
        int t1
        z = passsize * 128 + 45                 /* music font
        t1 = x
        if c10 = 0
          --x
        end
        kscrdat = ""
        perform subj
        if c10 = 0
          x += hpar(106)
        else
          x += hpar(107)
        end
        perform subj
        x = t1
      return

 ┌────────────────────────────────────────────────────┐
 │P 12. number                                        │
 │                                                    │
 │    Purpose:  Create subobject for number           │
 │                                                    │
 │    Inputs:  a = number                             │
 │             dv2 = center position for number       │
 │                                                    │
 │    Outputs: dv3 = right boundary of number         │
 │                                                    │
 │             x,z sent to subj                       │
 │                                                    │
 └────────────────────────────────────────────────────┘

      procedure number
        x = dv2 - hpar(21)
        if a > 99
          x = dv2 + hpar(21)
        else
          if a > 9
            x = dv2
          end
        end
        dv3 = x + hpar(20)
        kscrdat = ""
NU1:    a /= 10
        z = rem + 71                      /* music font
        perform subj
        if a = 0
          return
        end
        x -= hpar(20)
        goto NU1

 ┌──────────────────────────────────────────────────────────────┐
 │P 13. setdots                                                 │
 │                                                              │
 │    Purpose:  typeset sub-object dot(s)                       │
 │                                                              │
 │    Inputs:  c3 = pointer into set array for this note        │
 │            obx = horizontal position of object               │
 │            oby = vertical position of object                 │
 │       passsize = note size (full size, cue size)             │
 │                                                              │
 └──────────────────────────────────────────────────────────────┘

      procedure setdots
        int t1,t2,t3,t4,t5,t6
        t4 = ts(c3,DOT)
        if t4 > 0
          t1 = t4 >> 4                          /* code modified 12-24-96
          t1 /= INT10000
          t2 = rem
          if t2 > (INT10000 >> 1)
            t2 -= INT10000
            ++t1
          end

          t6 = 18                               /* New code 05/02/03 extension dot code = 18
          perform getpxpy (t6,c3)

          if pxx = 1
            x = obx + px
          else
            x = obx + t1 + px
          end
          if pyy = 1
            y = oby + py
          else
            y = oby + t2 + py
          end
                                                /* end New code

          z = 128 * passsize + 44               /* music font
          kscrdat = ""
          perform subj                          /* first dot
          if t4 & 0x03 = 3
            t3 = hpar(91)
            if passsize = CUESIZE
              t3 = t3 * 8 / 10
            end
            x += t3
            perform subj                        /* second dot
          end

     added code  12-24-96

          if t4 & 0x04 = 4
            t3 = hpar(91)
            if passsize = CUESIZE
              t3 = t3 * 8 / 10
            end
            x += t3
            perform subj                        /* third dot
          end
          if t4 & 0x08 = 8
            t3 = hpar(91)
            if passsize = CUESIZE
              t3 = t3 * 8 / 10
            end
            x += t3
            perform subj                        /* fourth dot
          end
        end
      return

 ┌────────────────────────────────────────────────────────────────┐
 │P 14. setrest (t6)                                              │
 │                                                                │
 │    Purpose:  write object rest                                 │
 │                                                                │
 │    Inputs:  c1       = pointer into set array for this rest    │
 │             obx      = horizontal position of rest             │
 │             oby      = vertical position of rest               │
 │             c3       = oby offset (for grand staff)            │
 │             ntype    = type of note (e.g. sixteenth)           │
 │             passsize = rest type (full size, cue size)         │
 │             passtype = type of pass (reg,cue,grace,cuegrace)   │
 │             passnum  = pass number for this rest               │
 │             inctype  = increment type for next node            │
 │                          with a new spn (used in putobj)       │
 │             opt_rest_flag = put out rest with small r          │
 │                                                                │
 │    Output:  t6       = amount of space taken up                │
 │                                                                │
 │    Operation:  In addition to writing the object rest, this    │
 │                procedure must also check to see if the rest is │
 │                the beginning or end of a tuplet group.  In the │
 │                former case, the tuplet array, tuar, must be    │
 │                constructed; in the latter case, the tuplet     │
 │                super-object must be compiled and written out.  │
 └────────────────────────────────────────────────────────────────┘

      procedure setrest (t6)
        str temp.100
        int t1,t2,t3,t4,t5,t6,t7,t8,t9
        int t10
        int staff,track,pri_staff,p21,p22,p4,p5,p6,p71,p72,p8,p12

        if scr_flag = 1
          pri_staff = 0
          track = ts(c1,TRACK_NUM)
          staff = ts(c1,STAFF_NUM) + 1
          if track > 0
            pri_staff = trackstave(opbarnum,track,3)
          end

     Compute values for P2 P4 P5 P6 P7 P8 and P12

          p21 = staff
          p22 = track
          t1 = oby

     P4 may be modified by print suggestions

          t4 = ts(c1,TSR_POINT)
          t8 = ors(tsr(t4){2})                               /* 05/02/03 code revised
          if bit(0,t8) = 1
            t5 = ors(tsr(t4){4})
            if t5 > 0
              t5 = t5 - 128 * notesize
              if t5 >= 0
                t5 = t5 + 5 / 10
              else
                t5 = t5 - 5 / 10                             /* verified as working properly
              end
              if bit(2,t8) = 1                               /* position is "absolute"
                t1 = t5
              else                                           /* position is "relative"
                t1 = t1 + t5
              end
            end
          end

           Assumed defaults for rests
          ============================
              rest   MUSED   SCORE
               w       28      0
               h       28      0
               q       28      0
               e       28      0
               s       28      0
               t       14      0
               x       14      0

          p4 = (0 - t1) / vpar(1) + 4
          if ntype < SIXTEENTH
            p4 -= 2
          end

          p5 = 7 - ntype                 /* MUSEDATA q = 7, SCORE q = 0
          if ts(c1,CLAVE) = 200
            p6 = -1
          else
            p6 = 0
            t3 = ts(c1,DOT)
            t8 = t3 & 0x0f
            if t8 > 0
              p6 = int("1.2...3.......4"{t8})
            end
          end
          p71 = 10000 * note_dur / divspq
          p71 = p71 / 10000
          p72 = rem
          p8 = 0
          if bit(14,ts(c1,SUBFLAG_1)) = 1
            p8 = 1                          /* actually -1
          end
          p12 = 0
          if pri_staff > 0
            if pri_staff = 1 and staff = 2
              p12 = 2
            end
            if pri_staff = 2 and staff = 1
              p12 = 1
            end
            p21 = pri_staff                        /* set P2 to primary staff
          end
          if ts(c1,CLAVE) = 200 and pri_staff > 0
            p12 = 0                                /* force "silent" rests to primary staff
          end

          kscrdat = " | P2=" // chs(p21) // "." // chs(p22) // " P4=" // chs(p4)
          kscrdat = kscrdat // " P5=" // chs(p5) // " P6=" // chs(p6)
          kscrdat = kscrdat // " P7=" // chs(p71) // "."
          if p72 < 10
            kscrdat = kscrdat // "0"
          end
          if p72 < 100
            kscrdat = kscrdat // "0"
          end
          if p72 < 1000
            kscrdat = kscrdat // "0"
          end
          kscrdat = kscrdat // chs(p72)
          if p8 = 0
            kscrdat = kscrdat // " P8="
          else
            kscrdat = kscrdat // " P8=-"
          end
          kscrdat = kscrdat // chs(p8) // " P12=" // chs(p12)
        end

        t10 = c3
        x = obx
        y = oby
        t1 = 0
        if ts(c1,CLAVE) = 200 and scr_flag = 1
          t6 = 0
          z = 0
          perform subj
          kscrdat = ""
          goto SRST1
        end
        if ntype > QUARTER
          t6 = hpar(87)                   /* total horizontal space taken
        else
          t6 = hpar(88)                   /* total horizontal space taken
        end

        if ntype > SIXTEENTH
          z = 128 * passsize + 55 - ntype       /* music font
          perform subj
          kscrdat = ""
        else
          y += notesize
          if ntype < THIRTY_SECOND
            y = 4 - ntype * notesize + y
          end
          z = 128 * passsize + 49               /* music font
          perform subj
          kscrdat = ""
          ++z
          if passsize = FULLSIZE
            t3 = notesize
            t4 = hpar(54)
          else
            t3 = vpar(65)
            t4 = hpar(89)
          end
          t2 = ntype
          loop while t2 < EIGHTH
            y -= t3
            x += t4
            t6 += t4                      /* total horizontal space taken
            ++t1
            perform subj
            ++t2
          repeat
        end
        if ts(c1,DOT) > 0
          t3 = ts(c1,DOT)
          t8 = t3 & 0x0f                  /* actual DOT code  (modified 12-24-96)
          t3 >>= 4                        /* code modified 12-24-96
          t3 /= INT10000
          t7 = rem
          if t7 > (INT10000 >> 1)
            t7 -= INT10000
            ++t3
          end
          y = oby + t7
          x += t3
          t6 = vpar(1)
          if passsize = CUESIZE
            t6 = t6 * 8 / 10              /* space for dot
          end
          t6 += t3
          z = 128 * passsize + 44               /* music font
          perform subj                          /* first dot
          if t8 & 0x02 = 2
            t5 = hpar(91)
            x += t5
            perform subj                       /* second dot
            t6 += t5
          end

      code added 12-24-96

          if t8 & 0x04 = 4
            t5 = hpar(91)
            x += t5
            perform subj                       /* third dot
            t6 += t5
          end
          if t8 & 0x08 = 8
            t5 = hpar(91)
            x += t5
            perform subj                       /* fourth dot
            t6 += t5
          end

        end
SRST1:
        passback t6                       /* total horizontal space taken


     New 10/15/07

        jtype = "R"
        if opt_rest_flag = 0
          jtype = "R"
        else
          jtype = "r"
        end

        jcode = ntype
        out = "0"
        if bit(4,ts(c1,SUPER_FLAG)) = 1   /* if begin tuplet
          ++snum
          tuar(passtype,passnum,TU_SNUM) = snum
          tuar(passtype,passnum,TU_Y1) = y
          tuar(passtype,passnum,TU_Y2) = y
          tuar(passtype,passnum,TU_FSTEM) = DOWN   /*  (default)
          t7 = 0
          if bit(6,ts(c1,SUPER_FLAG)) = 1         /* tuplet has a bracket
            t7 = ts(c1,SUPER_FLAG) & 0x3c0        /* bits 6,7,8,9 03-21-97
            t7 <<= 2
          end
          tuar(passtype,passnum,TU_FSTEM) += t7   /* tuplet flags 03-21-97
          out = "1 " // chs(snum)
        end
        if bit(5,ts(c1,SUPER_FLAG)) = 1   /* if end tuplet
          t7 = tuar(passtype,passnum,TU_FSTEM) & 0xff
          goto TPFF(tpflag+1)
TPFF(1):                                   /* default tuplet placement
TPFF(2):                                   /* place tuplet near note heads
          if t7 = UP
            goto TPFFA
          else
            goto TPFFB
          end
TPFF(3):                                   /* place tuplet near stems
          if t7 = UP
            goto TPFFB
          else
            goto TPFFA
          end
TPFF(4):                                   /* place all tuplets above notes
          goto TPFFB
TPFF(5):                                   /* place all tuplets below notes
          goto TPFFA

TPFFA:
          t3 = tuar(passtype,passnum,TU_Y2) + notesize + vpar(64)
          t4 = notesize * 6
          if t7 <> UP
            t3 += vpar(7)
          end
          if t3 < t4
            t3 = t4
          end
          t9 = 4          /* tips up 03-21-97
          goto TPFFC
TPFFB:
          t3 = tuar(passtype,passnum,TU_Y2) - notesize
          t4 = 0 - vpar(1)
          if t7 = UP
            t3 -= vpar(7)
          end
          if t3 > t4
            t3 = t4
          end
          t9 = 0          /* tips down 03-21-97
TPFFC:
          t3 -= tuar(passtype,passnum,TU_Y1)
          t5 = t4 - oby
          out = "1 " // chs(tuar(passtype,passnum,TU_SNUM))
        end

  fermata over rest

        kscrdat = ""
        if bit(14,ts(c1,SUBFLAG_1)) = 1
          t2 = 15                       /* upright fermata code = 15
          perform getpxpy (t2,c1)

          x = obx + px
          if pyy > 0
            y = py
          else
            y = py - vpar(1)
          end
          z = 101                         /* music font
          perform subj
        end
        if bit(15,ts(c1,SUBFLAG_1)) = 1
          t2 = 16                       /* inverted fermata code = 16
          perform getpxpy (t2,c1)

          x = obx + px
          z = 102                         /* music font
          y = vpar(10)                    /* changed 05/02/03
          if pyy > 0
            y = py
          else
            y += py
          end
          perform subj
        end

     New code (11-11-93)  Duration attribute of rest

        ++sobcnt
        sobl(sobcnt) = "A D " // chs(note_dur) // " " // chs(divspq*4)

        if sobcnt = 1
          pcode = z
        else
          pcode = sobcnt
        end
        t7 = inctype
        if ts(c1,CLAVE) = 101             /* if movable rest
          inctype = 10000
        end

     New code add 01/03/04 to deal with special case of type 7 whole rests

        if ts(c1,CLAVE) = 102             /* flag whole rest as potentially "removable"
          inctype = 10001
        end
        oby += t10

        Now look for print suggestions for this note object

        putobjpar = 0
        t4 = ts(c1,TSR_POINT)
        pcontrol = ors(tsr(t4){1})                      /* 05/02/03
        px = ors(tsr(t4){3}) << 8
        py = ors(tsr(t4){4}) << 16
        t1 = ors(tsr(t4){2}) << 24
        putobjpar = t1 + px + py + pcontrol             /* Note: order of data has been changed

        jscrdat = ""
        perform putobj
        inctype = t7
        if bit(5,ts(c1,SUPER_FLAG)) = 1   /* if end tuplet
          t1 = tuar(passtype,passnum,TU_FSTEM) >> 8           /* tuplets flags 03-21-97
          if t1 > 0
            t1 >>= 1                /* remove bracket present flag
            t1 <<= 5
            t9 |= t1
            t9 |= 0x02              /* bracket present flag
          else
            t9 = 1
          end
          ++outpnt

       New 11/05/05  Convert TUPLE to 1000 * n1 + n2 format and get x,y adjustments

          t1 = ts(c1,TUPLE) & 0xffff
          t2 = t1 >> 8
          t1 &= 0xff
          t2 *= 1000
          t1 += t2

          t6 = ts(c1,TUPLE) & 0xff0000        /* x adjustment
          t6 >>= 16
          if t6 > 0
            t6 = t6 - 128                     /* center to zero
          else
            t6 = 0
          end

          t4 = ts(c1,TUPLE) & 0xff000000      /* y adjustment
          t4 >>= 24
          if t4 > 0
            t4 = t4 - 128                     /* center to zero
          else
            t4 = 0
          end
          t3 += t4
          t5 += t4


          tput [Y,outpnt] H ~tuar(passtype,passnum,TU_SNUM)  X ~t9  ~ts(c1,TUPLE)  0 ~t3  0 ~t5  0
          tput [Y,outpnt] H ~tuar(passtype,passnum,TU_SNUM)  X ~t9  ~t1  ~t6  ~t3  ~t6  ~t5  0
          tuar(passtype,passnum,TU_SNUM) = 0        /* New added from s2ed
          tpflag = global_tpflag
        end
      return

 ┌─────────────────────────────────────────────────────────────────────┐
 │P 15. putobj                                                         │
 │                                                                     │
 │    Purpose:  write object and sub-objects to intermediate list      │
 │                                                                     │
 │    Inputs:  jtype = object type (field 2)                           │
 │             jcode = object code (field 3)                           │
 │             obx   = object offset from staff x-position (field 4)   │
 │             oby   = object offset form staff y-position (field 5)   │
 │             pcode = print code (field 6) (or sobl counter)          │
 │             spn   = space node (field 7)                            │
 │             inctype = increment type for next node with a new spn   │
 │             out     = fields 9 --                                   │
 │             temp3   = occationally temp3 is used in place of        │
 │                         sobl(1) when there is only 1 subobject      │
 │             sobl()  = subobject line                                │
 │             jscrdat = SCORE data appended to end of object (03/21/03)
 │             c1,c2   = pointer to first and last elements in         │
 │                         ts(.,.) array for this object               │
 │                                                                     │
 │             putobjpar = parameters modifying operation of putobj    │
 │                                                                     │
 │                putobjpar & 0x01 = control    0 = no modifications   │
 │                                                    in this byte     │
 │                                              1 = possible mods in   │
 │                                                    this byte        │
 │                                                                     │
 │                putobjpar & 0x06 = blank flag 0 = no blanking        │
 │                                              2 = blank all sub-obj  │
 │                                              4 = replace all sub-obj│
 │                                                    with one         │
 │                                                    extension dot    │
 │                                                                     │
 │                putobjpar & 0xf0 = (four) various flags              │
 │                  For Notes, Grace Notes, Cue Notes ("NGQ" con jtype)│
 │                                           0x10 = stem present       │
 │                                                   0 = no stem       │
 │                                                   1 = stem          │
 │                                           0x20 = stem direction     │
 │                                                   0 = UP            │
 │                                                   1 = DOWN          │
 │                                           0x40 = note/chord         │
 │                                                   0 = single note   │
 │                                                   1 = chord         │
 │                                                                     │
 │                                                                     │
 │                putobjpar & 0x00ff00   = x position data + 128       │
 │                                          (in tenths of notesize)    │
 │                                         0 = no data                 │
 │                                                                     │
 │                putobjpar & 0xff0000   = y position data + 128       │
 │                                          (in tenths of notesize)    │
 │                                         0 = no data                 │
 │                                                                     │
 │                putobjpar & 0xff000000 = position data flags         │
 │                                                                     │
 │                                  0x01 = data active flag            │
 │                                  0x02 = x data flag                 │
 │                                         1 = x location relative to  │
 │                                             obx                     │
 │                                         0 = modification to         │
 │                                             x location as calculated│
 │                                  0x04 = y data flag                 │
 │                                         1 = y location on staff     │
 │                                         0 = modification to         │
 │                                             y location as calculated│
 │                                                                     │
 │             fix_next_inctype = static variable initialized at BIG,  │  New 01/19/04
 │                                  set and used only by putobj.       │
 │                                Variable provides a means for putobj │
 │                                to "remember" when it has altered an │
 │                                inctype, and a way to "add back" any │
 │                                amount taken away.                   │
 │                                                                     │
 │    Outputs: sobcnt set to 0                                         │
 │             supcnt set to 0                                         │
 │                                                                     │
 │    Internal variable:  oldspn = spn from previous object            │
 └─────────────────────────────────────────────────────────────────────┘

      procedure putobj
        str temp.180,super.180
        str params.30(20)
        int oldspn,t
        int t1,t2,t3,t4,t5,t6,t7,t8,t9
        int s1,s2,s3,s4,s5,s6,s7,s8,s9
        int stem,chord
        int high,low,highpoint,lowpoint
        int highstem,lowstem,stemlength
        int nflags,slash,pcnt
        int grflag

     This code added 01/19/04 to fix the accumulation of inctypes

        if fix_next_inctype > 0 and inctype > 0
          putc     Attempting to adjust the next Inctype from ~inctype  ...
          inctype -= fix_next_inctype
          if inctype < 0
            inctype = 0
          end
          putc to ~inctype
          fix_next_inctype = 0
        end



        New Code 09/14/03
        -----------------
        If jtype = "I", then inctype may need to be recalculated from the ts(.) array

        if jtype = "I" and a1 > 1
          t3 = 10000
          loop for t1 = a1 - 1 to 1 step -1
            t2 = ts(t1,DIV)
            if t2 < ts(a1,DIV)
              t3 = ts(a1,DIV) - t2 * 576 / divspq
              t1 = 1
            end
          repeat

          if t3 <> 10000 and t3 <> inctype
            putc   Caution  Inctype for "I" type object changed from ~inctype  to  ~t3
            fix_next_inctype = t3 - inctype      /* fix_next_inctype set 01/19/04
            inctype = t3
          end
        end

        t = inctype
        if t <> 10000 and t <> 10001             /* 10001 added 01/03/04
          if spn = oldspn
            t = 0
          end
          if spn = 1
            t = 0
          end
        end
        stem = 0
        if "NGQ" con jtype and jcode < WHOLE
          stem = putobjpar & 0xf0
          stem >>= 4
          putobjpar &= 0xffffff0f                /* strip stem codes from putobjpar
        end

     Determine: t1 = final obx   as modified by print suggestions
                t2 = final oby                                       05/02/03

        px = putobjpar >> 8   & 0xff
        py = putobjpar >> 16  & 0xff
        if px > 0
          px = px - 128 * notesize / 10
        end
        t1 = obx + px
        if py > 0
          py = py - 128 * notesize / 10
          t4 = putobjpar >> 24  & 0xff
          if bit(2,t4) = 1
            t2 = py
            if oby > 700
              t2 += 1000
            end
          else
            t2 = oby + py
          end
        else
          t2 = oby
        end

     If putobjpar & 0x01 = 1, then we are dealing with certain rennaisance notation
       which allows a note duration to extend beyond a bar line.  In this case,
       the note beyond the barline may be blanked entirely (putobjpar & 0x02 = 1),
       or it may be replaced with an extension dot (putobjpar & 0x04 = 1).

        if (bit(0,putobjpar)) = 1
          putobjpar &= 0xff
          t3 = pcode
          t4 = putobjpar >> 1
          if t4 = 1 or t4 = 2
            if t3 > 0 and t3 < 32
              if sobl(1) = ""
                t3 = 0
              else
                t6 = 0
                if t4 = 2
                  ++t6
                  t8 = t2 / vpar(2)
                  if rem = 0
                    t8 = vpar(1) - notesize
                  else
                    t8 = 0
                  end

                  t9 = DOT_CHAR
                  sobl(t6) = "K 0 " // chs(t8) // " " // chs(t9)
                end
                loop for t5 = 1 to t3
                  if sobl(t5){1} = "A"
                    ++t6
                    sobl(t6) = sobl(t5)
                  end
                repeat
                t3 = t6
              end
            end
          end
        else
          t3 = pcode
        end

        ++outpnt

      11/20/06  This code added for special case of a slur terminating
                on a non-printed note.

        if jtype = "N" and jcode = 0
          t3 = 0
        end
                  End of 11/20/06 addition

        if scr_flag = 1
          tput [Y,outpnt] J ~jtype  ~jcode  ~t1  ~t2  ~t3  ~spn  ~t  ~out  ~jscrdat
#if OBJ_REPORT
          dputc J ~jtype  ~jcode  ~t1  ~t2  ~t3  ~spn  ~t  ~out  ~jscrdat
#endif
        else
          tput [Y,outpnt] J ~jtype  ~jcode  ~t1  ~t2  ~t3  ~spn  ~t  ~out
#if OBJ_REPORT
          dputc J ~jtype  ~jcode  ~t1  ~t2  ~t3  ~spn  ~t  ~out
#endif
        end


     Look for marks that could be incorporated with this object

        super = ""
        if jtype = "N"
          tget [Y,outpnt-1] temp .t5 s1 s2 s3 s4 s5 s6 s7 s8
          if temp{1} = "H"
            super = temp
            tget [Y,outpnt-2] temp .t5 s1 s2 s3 s4 s5 s6 s7 s8
          end
          if temp{1,3} = "J M" and s2 = t1 and s5 = spn and s7 = 1
            if super = ""
              --outpnt
            else
              outpnt -= 2
            end
            out = trm(out)
            out = out // " "
            s9 = int(out)
            ++s9
            out = chs(s9) // out{sub..} // chs(s8)
            t = s6
            if scr_flag = 1
              tput [Y,outpnt] J ~jtype  ~jcode  ~t1  ~t2  ~t3  ~spn  ~t  ~out  ~jscrdat
            else
              tput [Y,outpnt] J ~jtype  ~jcode  ~t1  ~t2  ~t3  ~spn  ~t  ~out
            end
          else
            super = ""
          end
        end

        oldspn = spn
        if t3 > 0 and t3 < 32
          if sobl(1) = ""
            ++outpnt
            tput [Y,outpnt] ~temp3
#if OBJ_REPORT
            dputc ~temp3
#endif
          else
            if scr_flag = 1

     We are going to get a little fancy here.  At this point, we can determine
     some information that SCORE would like to have.

     A. For NOTE heads:  By having information on stem direction and
           note vs. chord, by looking at the note-object record and by
           searching through the sub-objects, we can determine:

        1. whether the note/chord has a separate stem or is
             allied with a beam

        2. if the note/chord has a separate stem,

           a) which notehead is at the note-end of the chord

           b) the stem direction, stem length, and number of
                flags for this chord (elements of P5, P8, and P9),
                which can be attached to this notehead sub-object.

        3. if the note/chord is allied with a beam,

           a) whether this is a single note or a chord

           b) if a chord, which notehead is at the note-end
                of the chord and the stem direction (number
                of flags is zero), both of which can be
                attached to this notehead sub-object.

        Note: In theory, autoscr had this information at the time it
              typeset the sub-objects, but I looked through the code
              and found it problematic to deduce precisely what
              autoscr is doing.  We could do this, but it would take
              quite a while to get everything right.  Instead, why not
              just analyze what autoscr actually did in each situation
              and report this to SCORE.

              if "GNQ" con jtype and jcode < WHOLE
                grflag = mpt & 0x01

                if bit(0,stem) = 0
                  putc stem = ~stem
                  putc No stem direction specified for half note or less
                  dputc Program needs fixing, and so does the stage2 file.
                  stop
                end
                chord = stem >> 2       /* 1 = chord
                stem &= 0x02            /* just look at this bit
                stem >>= 1              /* 0 = UP 1 = DOWN
                nflags = 0
                slash = 0
                stemlength = 0

                highstem = 10000
                lowstem = -10000
                high = 10000
                low = -10000
                loop for sobcnt = 1 to t3
                  temp = sobl(sobcnt)
                  temp = temp // pad(80)
                  if temp{1} = "K"
                    sub = 2
                    t4 = int(temp{sub..})
                    t5 = int(temp{sub..})
                    t6 = int(temp{sub..})
                    if chr(t6) in [42,43,170,171]
                      if t5 < high
                        highpoint = sobcnt
                        high = t5
                      end
                      if t5 > low
                        lowpoint = sobcnt
                        low = t5
                      end
                    end
                    if chr(t6) in [51..62,179..190]
                      t7 = t5
                      t8 = t5
                      if t6 = 59                   /* 59 full length up
                        t7 = t5 - 28
                        goto POJ1
                      end
                      if t6 = 60                   /* 60 full length down
                        t8 = t5 + 29
                        goto POJ1
                      end
                      if t6 < 55
                        nflags = 1
                        if t6 = 53                 /* 53 up-eighth
                          t7 = t5 - 47
                          goto POJ1
                        end
                        if t6 = 54                 /* 54 down-eighth
                          t8 = t5 + 47
                          goto POJ1
                        end
                        if t6 = 51                 /* 51 short up-eighth
                          t7 = t5 - 40
                          goto POJ1
                        end
                        if t6 = 52                 /* 52 short down-eighth
                          t8 = t5 + 40
                          goto POJ1
                        end
                      end
                      if t6 < 59
                        if t6 = 55                 /* 55 up-sixteenth
                          t7 = t5 - 51
                          nflags = 2
                          goto POJ1
                        end
                        if t6 = 56                 /* 56 down-sixteenth
                          t8 = t4 + 51
                          nflags = 2
                          goto POJ1
                        end
                        if t6 = 57                 /* 57 up-add-eighth
                          t7 = t5 - 51
                          ++nflags
                          goto POJ1
                        end
                        if t6 = 58                 /* 58 down-add-eighth
                          t8 = t4 + 51
                          ++nflags
                          goto POJ1
                        end
                      end
                      if t6 = 61                 /* 61 notesize up
                        t7 = t5 - 14
                        goto POJ1
                      end
                      if t6 = 62                 /* 62 notesize down
                        t8 = t5 + 15
                        goto POJ1
                      end
                      if t6 = 179                /* 179 up-eight + slash
                        t7 = t5 - 38
                        nflags = 1
                        slash = 1
                        goto POJ1
                      end
                      if t6 = 181                /* 181 up-eighth
                        t7 = t5 - 38
                        nflags = 1
                        goto POJ1
                      end
                      if t6 = 180                /* 180 down-eight + slash
                        t8 = t5 + 38
                        nflags = 1
                        slash = 1
                        goto POJ1
                      end
                      if t6 = 182                /* 182 down-eighth
                        t8 = t5 + 38
                        nflags = 1
                        goto POJ1
                      end
                      if t6 = 183                /* 183 up-sixteenth
                        nflags = 2
                        t7 = t5 - 41
                      end
                      if t6 = 184                /* 184 down-sixteenth
                        nflags = 2
                        t8 = t5 + 41
                      end
                      if t6 = 185                /* 185 up-add-eighth
                        ++nflags
                        t7 = t5 - 41
                      end
                      if t6 = 186                /* 186 down-add-eighth
                        ++nflags
                        t8 = t5 + 37
                      end
                      if t6 = 187                /* 187 full length up
                        t7 = t5 - 28
                      end
                      if t6 = 188                /* 188 full length down
                        t8 = t5 + 29
                      end
                      if t6 = 189                /* 189 notesize up
                        t7 = t5 - 14
                      end
                      if t6 = 190                /* 190 notesize down
                        t8 = t5 + 15
                      end
POJ1:
                      if t7 < highstem
                        highstem = t7
                      end
                      if t8 > lowstem
                        lowstem = t8
                      end
                    end
                  end
                repeat
                stemlength = lowstem - highstem
                t8 = low - high                     /* t8 = spread
                if t8 + vpar(3) >= stemlength - 2   /* then this unit is under a beam
                  stemlength = 100000               /* P8 for notes under a beam
                else
                  stemlength *= 100                 /* work in 100ths
                  if grflag = 1                     /* a fudge, but it may work
                    stemlength += (260 * vpar(1))
                  end

                  if jcode >= EIGHTH
                    t8 = 700 * vpar(1)              /* set zero to 7 scale steps
                  else
                    t8 = 793 * vpar(1)              /* set zero to 7.93 scale steps
                  end                               /*   SCORE printing style
                  stemlength -= t8
                  stemlength /= vpar(1)             /* reduce to scale steps now
                end
                if stem = UP
                  t8 = lowpoint
                else
                  t8 = highpoint
                end
                temp = sobl(t8) // pad(120)
                loop for t7 = 1 to 20
                  params(t7) = ""
                repeat
                sub = 1
POJ2:
                if temp{sub..} con "P"
                  t4 = sub
                  t7 = int(temp{sub+1..})
                  if temp{sub..} con " "
                    t5 = sub
                  end
                  params(t7) = temp{t4..t5}
                  goto POJ2
                end

          Note: The code below is potentially in ERROR because it may need to
                be applied to all notes in the chord, not just the controlling note.
                (07/28/03)

                if temp con "Dots"
                  t4 = sub-1
                  if temp{sub..} con " "
                    t5 = sub
                  end
                  params(20) = temp{t4..t5}
                end

                if "GQ" con jtype
                  t4 = int(params(4){4..})
                  params(4) = "P4="                             07/28/03
                  if t4 < 0                                     This code is in the wrong
                    t4 = 0 - t4                                 place.  It must be applied
                    params(4) = params(4) // "-"                to all notes on a chord, not
                  end                                           just the controlling note.
                  t4 += 100                                     See new code below.
                  params(4) = params(4) // chs(t4) // " "
                end

                if params(5) = ""
                  t5 = stem + 1 * 10
                  params(5) = "P5=" // chs(t5) // " "
                else
                  t5 = stem + 1
                  params(5) = "P5=" // chs(t5) // params(5){4..}
                end

                if stemlength < 0
                  stemlength = 0 - stemlength
                  params(8) = "P8=-"
                else
                  params(8) = "P8="
                end
                t4 = stemlength / 100
                t5 = rem
                if slash = 1
                  stemlength += 100
                end
                params(8) = params(8) // chs(t4) // "."
                if t5 < 10
                  params(8) = params(8) // "0"
                end
                params(8) = params(8) // chs(t5)

                if nflags > 0
                  if params(9) = ""
                    params(9) = "P9=" // chs(nflags) // ".00"
                  else
                    t5 = int(params(9){4..})
                    t6 = sub
                    t5 += nflags
                    params(9) = "P9=" // chs(t5) // params(9){t6..}
                  end
                end

                if temp con "|"
                  temp = temp{1,mpt}
                end
                loop for t7 = 1 to 9
                  params(t7) = trm(params(t7))
                  if params(t7) <> ""
                    temp = temp // " " // params(t7)
                  end
                repeat
                params(20) = trm(params(20))
                if params(20) <> ""
                  temp = temp // " " // params(20)
                end
                loop for t7 = 10 to 19
                  params(t7) = trm(params(t7))
                  if params(t7) <> ""
                    temp = temp // " " // params(t7)
                  end
                repeat
                sobl(t8) = temp

        If note is Grace or Cue, you must modify P4 for all notes in a chord (07/28/03)

                if "GQ" con jtype
                  loop for sobcnt = 1 to t3
                    temp = sobl(sobcnt)
                    temp = temp // pad(170)
                    if temp{1} = "K"
                      if temp con "P4="
                        t4 = sub
                        if temp{sub..} con " "
                          t5 = sub
                        end
                        params(4) = temp{t4..t5}                     /* e.g. "P4=12 "

                        t7 = int(params(4){4..})
                        params(4) = "P4="
                        if t7 < 0
                          t7 = 0 - t7
                          params(4) = params(4) // "-"
                        end
                        t7 += 100
                        params(4) = params(4) // chs(t7) // " "      /* e.g. "P4=112 "

                        temp = temp{1..t4-1} // params(4) // temp{t5+1..}

                        if jcode = 0

                          dputc Line = ~temp

                          if temp con "P8="

                            t4 = sub
                            if temp{sub..} con " "
                              t5 = sub
                            end
                            params(8) = temp{t4..t5}                     /* e.g. "P8=0.09 "

                            t7 = int(params(8){4..})
                            if params(8){sub} = "."
                              t8 = int(params(8){sub+1..})               /* e.g. t8 = 9
                            else
                              t8 = 0
                            end

                            params(8) = "P8="
                            if t7 < 0
                              t7 = 0 - t7
                              params(8) = params(8) // "-"
                            end
                            t7 += 100

                            params(8) = params(8) // chs(t7)
                            if t8 > 0
                              if t8 < 10
                                params(8) = params(8) // ".0"   /* e.g. "P8=100.09 "
                              else
                                params(8) = params(8) // "."
                              end
                              params(8) = params(8) // chs(t8) // " "
                            else
                              params(8) = params(8) // " "
                            end

                            temp = temp{1..t4-1} // params(8) // temp{t5+1..}
                          end

                          dputc New Line = ~temp

                        end

                        sobl(sobcnt) = trm(temp)
                      end
                    end
                  repeat
                end
              end

        End of 07/28/03 addition

            end

     New 03/18/06 constructing "A" type records

       1. First identify all ties connected to notes

            if xdata_flag = 1 and scr_flag = 0
              if "NGR" con jtype
                s5 = mpt
                s2 = 0
                if s5 < 3
                  s3 = 0
                  loop for s1 = c1 to c2
                    if bit(0,ts(s1,SUPER_FLAG)) = 1      /* if tie starts
                      ++s2
                    end
                    ++s3
                  repeat

       2. Append "tie" digit to "A D" record

                  s4 = 0
                  if s2 > 0
                    s4 = 1
                    if s2 < s3
                      s4 = 2
                    end
                  end
                  sobl(t3) = sobl(t3) // " " // chs(s4)
                else
                  sobl(t3) = sobl(t3) // " 0"
                end

       3. Construct "A P" records for this node

                loop for s1 = c1 to c2
                  ++t3
                  s6 = ts(s1,TRACK_NUM)
                  if s6 = 0
                    if tracknum_flag = 0
                      s6 = 1
                    else
                      putc Missing track number.  Possible error in stage2 file.
                      putc Run program again with measure numbers (Pxsm) to see
                      putc this might be.
                      putc
                      putc Program Halted
                      putc
                      stop
                    end
                  end
                  sobl(t3) = "A P " // chs(s6) // " " // chs(ts(s1,BASE_40))
                  if s5 < 3
                    if bit(0,ts(s1,SUPER_FLAG)) = 1      /* if tie starts
                      sobl(t3) = sobl(t3) // " 1"
                    else
                      sobl(t3) = sobl(t3) // " 0"
                    end
                    rest_flag(s6) = 0
                  else
                    sobl(t3) = sobl(t3) // " 0"          /* tricky code
                    s7 = rest_flag(s6)
                    if s7 > 0                            /* fixup previous rest for this track
                      tget [Y,s7] temp
                      s8 = int(temp{5..})
                      if temp{1,3} <> "A P" or s8 <> s6
                        putc Program error.  No rest fixup possible
                      else
                        temp = trm(temp)
                        temp{..} = "1"
                        tput [Y,s7] ~temp
                        --s7
                        tget [Y,s7] temp
                        temp = trm(temp)
                        temp{..} = "1"
                        tput [Y,s7] ~temp
                      end
                    end
                    rest_flag(s6) = outpnt + t3
                  end
                repeat
              end
            end

         End of 03/18/06 addition

            loop for sobcnt = 1 to t3
              ++outpnt
              tput [Y,outpnt] ~sobl(sobcnt)
#if OBJ_REPORT
              dputc ~sobl(sobcnt)
#endif
            repeat
          end
        end
        sobcnt = 0
        supcnt = 0
        if super <> ""
          ++outpnt
          tput [Y,outpnt] ~super
        end
      return

 ┌────────────────────────────────────────────────────────────┐
 │P 16. subj                                                  │
 │                                                            │
 │    Purpose:  write sub-object to intermediate list         │
 │                                                            │
 │    Inputs:  x = horizontal position of sub-object          │
 │             y = vertical position of sub-object            │
 │             z = character number                           │
 │             obx = object offset from staff x-position      │
 │             oby = object offset from staff y-position      │
 │             sobcnt = counter in intermediate list          │
 │             kscrdat = SCORE info to append to end of       │
 │                         sub-object record                  │
 └────────────────────────────────────────────────────────────┘

      procedure subj
        ++sobcnt
        sobx = x - obx
        soby = y - oby
        sobl(sobcnt) = "K " // chs(sobx) // " " // chs(soby) // " "
        if scr_flag = 1
          sobl(sobcnt) = sobl(sobcnt) // chs(z) // kscrdat
        else
          sobl(sobcnt) = sobl(sobcnt) // chs(z)
        end
      return

 ┌────────────────────────────────────────────────────────────┐
 │P 16a. subj2     /* Addition to Code 02/25/97 │                                                            │
 │    Purpose:  write "invisible" sub-object to               │
 │                intermediate list                           │
 │                                                            │
 │    Inputs:  x = horizontal position of sub-object          │
 │             y = vertical position of sub-object            │
 │             z = character number                           │
 │             obx = object offset from staff x-position      │
 │             oby = object offset from staff y-position      │
 │             sobcnt = counter in intermediate list          │
 └────────────────────────────────────────────────────────────┘

      procedure subj2
        ++sobcnt
        sobx = x - obx
        soby = y - oby
        sobl(sobcnt) = "k " // chs(sobx) // " " // chs(soby) // " "
        sobl(sobcnt) = sobl(sobcnt) // chs(z)
      return

 ┌────────────────────────────────────────────────────────────────┐
 │P 17. cancelsig (m, j, h, klave)                                │
 │                                                                │
 │    Purpose:  Write out cancellation of sharps or flats         │
 │                                                                │
 │    Inputs:   obx = object location                             │
 │              oby =   "       "                                 │
 │              x  = x starting point                             │
 │              h = number of sharps or flats to cancel           │
 │              j = one less than starting point in zak(.,.)      │
 │              m = selection   1 = sharps                        │
 │                              2 = flats                         │
 │                              3 = sharps (clef = tenor)         │
 │              klave = line on which to start calcellations      │
 │                        (from which y is computed)              │
 └────────────────────────────────────────────────────────────────┘

      procedure cancelsig  (m, j, h, klave)
        int m,j,h,klave,tenor
        getvalue m, j, h, klave

        tenor = 0
        if m = 3
          m = 1
          tenor = 1     /* exception for sharps in the tenor cler
        end

        z = 64
        kscrdat = ""
        loop for g = 1 to h
          if tenor = 0 or klave >= 0
            y = klave + 20 * notesize / 2 - vpar20
          else
            y = klave + 27 * notesize / 2 - vpar20
          end
          perform subj
          ++j
          y += zak(m,j)
          klave += zak(m,j)
          x += hpar(11)
        repeat

        passback klave
      return

 ┌────────────────────────────────────────────────────────────────┐
 │P 18. setmrest                                                  │
 │                                                                │
 │    Purpose:  Set multiple rests and terminating bar line       │
 │                                                                │
 │    Inputs:     p = horizontal starting point                   │
 │            mrest = number of rests to set                      │
 │          measnum = measure number for terminating bar line     │
 │            wrest = optional type 7 whole rest flag (01/03/04)  │
 │          jscrdat = SCORE info to append to end of              │
 │                       terminating bar line                     │
 │how_much_mrest(2) = divspq, divspm                              │
 │                                                                │
 │    Outputs:    p = new horizontal point                        │
 │            mrest = 0                                           │
 │                                                                │
 │    Operation: For multiple rests we need to communicate        │
 │                 P7 = rest's rhythmic duration                  │
 │                                                                │
 └────────────────────────────────────────────────────────────────┘

      procedure setmrest
        str temp.80
        int i,j
        int a2,a3,a4
        int t1                /* New 10/29/08

        if scr_flag = 1
          temp = jscrdat      /* save measure object's jscrdat string

          i = how_much_mrest(1)
          j = how_much_mrest(2)
          j = j * 10000 / i
          j /= 10000
          i = rem
          jscrdat = " | P7=" // chs(j) // "."
          if i < 10
            jscrdat = jscrdat // "0"
          end
          if i < 100
            jscrdat = jscrdat // "0"
          end
          if i < 1000
            jscrdat = jscrdat // "0"
          end
          jscrdat = jscrdat // chs(i)
        end

        putobjpar = 0
        if mrest > 1
          p += hpar(22)
          obx = p
          oby = vpar(3)
          x = obx
          y = oby
          z = 62
          kscrdat = ""
          perform subj
          y = oby + vpar(11)
          perform subj
          z = 92
          x = obx
          y = vpar(4)
          loop for i = 1 to 3
            perform subj
            x += 30
            p += 30
          repeat
          y = oby
          z = 62
          perform subj
          y = oby + vpar(11)
          perform subj
          dv2 = p - 45
          a = mrest

           Slight code modification 11/18/08

      In the case of musical parts, for notesize 21 anyway, I think
      the number above a multiple rest is easier to read if it is 2 dots
      above the middle line.  Admittedly, this is a magic number at the
      moment.

          if notesize = 21
            y = vpar(4) - 2
          else
            y = vpar(4)
          end



          perform number
          jtype = "S"
          jcode = 4
          out = "0"
          pcode = sobcnt
          spn = mrest

          perform putobj
          p += hpar(23)

          t1 = 1                /* New 10/29/08: 1 was the old value for J B (field 8)

        else
          obx = p + hpar(24)
          oby = vpar(4)
          ++outpnt

     New code 01/03/04, modified 03/13/06 to remove type 6 and type 7 Symbol objects

          if scr_flag = 1
            if wrest = 1
              tput [Y,outpnt] J R 9 ~obx  ~oby  46 1 10001 0 ~jscrdat
            else
              tput [Y,outpnt] J R 9 ~obx  ~oby  46 1 10000 0 ~jscrdat
            end
          else
            if wrest = 1
              tput [Y,outpnt] J S 7 ~obx  ~oby  46 0 0 0
              tput [Y,outpnt] J R 9 ~obx  ~oby  46 1 10001 0
            else
              tput [Y,outpnt] J S 6 ~obx  ~oby  46 0 0 0
              tput [Y,outpnt] J R 9 ~obx  ~oby  46 1 10000 0
            end
          end

          p += hpar(25)

                    New 10/29/08

        We need to try to compute a J B (field 8) value that mirrors
        the expected distance increment flag in a normal measure.
        We will use the data in: how_much_mrest(2) = divspq, divspm

          t1 = 576 * how_much_mrest(2) / how_much_mrest(1)



        end
        obx = p + hpar(36)

        if scr_flag = 1
          jscrdat = temp      /* restore measure object's jscrdat string
        else
          jscrdat = ""
        end

      03/07/06    Adding capability of setmrest to set "mdotted", "mdouble",
                  "mheavy2", "mheavy3", in addition to "measure".  No repeat dots,
                  endings, or other signs are allowed here.

        if mrest_line{2,6} = "easure"
          ++outpnt
          tput [Y,outpnt] J B ~measnum  ~obx  1 82 6913 1 0 ~jscrdat    /* Line below is new 10/29/08
          tput [Y,outpnt] J B ~measnum  ~obx  1 82 6913 ~t1  0 ~jscrdat
          p = obx + hpar(37)
        end
        if mrest_line{2,6} = "dotted"
          ++outpnt
          tput [Y,outpnt] J B ~measnum  ~obx  3 86 6913 1 0 ~jscrdat    /* Line below is new 10/29/08
          tput [Y,outpnt] J B ~measnum  ~obx  3 86 6913 ~t1  0 ~jscrdat
          p = obx + hpar(37)
        end

      hpar(44) = actual white space between two light lines
      hpar(45) = actual white space between heavy/light, light/heavy and heavy/heavy combinations
      hpar(79) = thickness of light line
      hpar(81) = thickness of heavy line

        if mrest_line{2,6} = "double"
          a2 = hpar(44) + hpar(79)
          a4 = obx + a2
          ++outpnt
          tput [Y,outpnt] J B ~measnum  ~a4  5 2 6913 1 0 ~jscrdat      /* Line below is new 10/29/08
          tput [Y,outpnt] J B ~measnum  ~a4  5 2 6913 ~t1  0 ~jscrdat
          ++outpnt
          tput [Y,outpnt] K -~a2  0 82
          ++outpnt
          tput [Y,outpnt] K 0 0 82
          p = a4 + hpar(37)
        end
        if mrest_line{2,6} = "heavy3"
          a2 = hpar(45) + hpar(81)
          ++outpnt
          tput [Y,outpnt] J B ~measnum  ~obx  9 2 6913 1 0 ~jscrdat     /* Line below is new 10/29/08
          tput [Y,outpnt] J B ~measnum  ~obx  9 2 6913 ~t1  0 ~jscrdat
          ++outpnt
          tput [Y,outpnt] K 0 0 84
          ++outpnt
          tput [Y,outpnt] K ~a2  0 82
          p = obx + hpar(37) + a2
        end
        if mrest_line{2,6} = "heavy2"
          a2 = hpar(45) + hpar(81) + hpar(79) - 1
          a3 = hpar(81) - 1
          a4 = obx + a2
          ++outpnt
          tput [Y,outpnt] J B ~measnum  ~a4  6 2 6913 1 0 ~jscrdat      /* Line below is new 10/29/08
          tput [Y,outpnt] J B ~measnum  ~a4  6 2 6913 ~t1  0 ~jscrdat
          ++outpnt
          tput [Y,outpnt] K -~a2  0 82
          ++outpnt
          tput [Y,outpnt] K -~a3  0 84
          p = a4 + hpar(37)
        end

        loop for i = 1 to MAX_STAFF
          loop for j = 1 to 45
            emptyspace(i,j) = hpar(37)
          repeat
        repeat
        mrest = 0
      return

 ┌─────────────────────────────────────────────────────────────────────┐
 │P 19. getspace                                                       │
 │                                                                     │
 │    Purpose:  Determine space parameter for particular note value    │
 │                                                                     │
 │    Inputs:    a5 = pointer into set array                           │
 │                                                                     │
 │    Outputs:   a6 = space parameter                                  │
 └─────────────────────────────────────────────────────────────────────┘

      procedure getspace
        int t1, t2, t3
        int gsp_ntype                 /* new 10/15/07

        if scr_flag = 1
          if ts(a5,CLAVE) = 200       /* silent rest gets no space
            a6 = 1                    /* 10/13/07 TEST
            return
          end
        end

        if ts(a5,CLAVE) = 101 or ts(a5,CLAVE) = 102       /* movable rest (altered 01/03/04)
          a6 = hpar(24) + hpar(25) - hpar(37)
          return
        end

        a6 = ts(a5,NTYPE) * 3

        gsp_ntype = ts(a5,NTYPE) & 0xff            /* new 10/15/07
        a6 = gsp_ntype * 3                         /* new 10/15/07

        if a6 = 0
          a6 = 3
        end
        --a6
        if ts(a5,DOT) > 0
          ++a6
        else
          if ts(a5,TUPLE) > 2
          if (ts(a5,TUPLE) & 0xffff) > 2          /* New 11/05/05
            --a6
          end
        end
        a6 = nsp(a6)
*  make extra space for up-flags
        if ts(a5,TYPE) = NOTE and bit(1,ts(a5,STEM_FLAGS)) = UP
          if ts(a5,BEAM_FLAG) = NO_BEAM and ts(a5,NTYPE) < QUARTER
          if ts(a5,BEAM_FLAG) = NO_BEAM and gsp_ntype    < QUARTER     /* new 10/15/07
            a6 += hpar(28)
            t3 = hpar(26) + hpar(28) + hpar(82)
            if a6 < t3
              loop for t1 = a5+1 to sct
                if ts(t1,DIV) > ts(a5,DIV)
                  loop for t2 = t1 to sct
                    if ts(t2,DIV) = ts(t1,DIV)
                      if ts(t2,TYPE) <= NOTE_OR_REST
                        if ts(t2,STAFF_NUM) = ts(a5,STAFF_NUM)
                          if ts(t2,CLAVE) >= ts(a5,CLAVE)
                            a6 = t3
                            t2 = sct
                          end
                        end
                      end
                    else
                      t2 = sct
                    end
                  repeat
                  t1 = sct
                end
              repeat
            end
          end
        end
*  allow mininum extra space if next note on staff has stem-down repeaters


*  make extra space for sixteenth and smaller rests
        if ts(a5,TYPE) = REST and ts(a5,NTYPE) < EIGHTH
        if ts(a5,TYPE) = REST and gsp_ntype    < EIGHTH        /* new 10/15/07
          a6 = 6 - ts(a5,NTYPE) * hpar(54) + a6
          a6 = 6 - gsp_ntype    * hpar(54) + a6                /* new 10/15/07
        end
*  shrink space if cue-size flag is set
        if bit(16,ts(a5,SUBFLAG_1)) = CUESIZE
          a6 = a6 * 8 / 10
        end
      return

 ┌────────────────────────────────────────────────────┐
 │P 20. wordspace                                     │
 │                                                    │
 │    Purpose:  Calculate length of word              │
 │                                                    │
 │    Inputs:    ttext   = word                       │
 │                  c5   = font number                │
 │               curfont = currently active font      │
 │                                                    │
 │    Outputs:   a5 = space taken up by word          │
 │                                                    │
 │               curfont possibly modified            │
 └────────────────────────────────────────────────────┘

      procedure wordspace
        int t1,t2,d1
        a5 = 0
*   get new spacing parameters, if needed
        perform spacepar



     Rewriting this section 04/22/04

        loop for t2 = 1 to len(ttext)
          if ttext{t2} = "\"
            if t2 = len(ttext)
              return 5
            end
            if "!@#$%^&*(-=" con ttext{t2+1}
              if mpt < 10
                ++t2
                a5 += mpt
                goto NXC
              else
                ++t2
                a5 -= (mpt - 9)
                goto NXC
              end
            end

        New 02/02/09

            if ttext{t2+1} = "+"
              ++t2
              a5 += spc(32)
              goto NXC
            end

            if t2 + 1 = len(ttext)
              return 5
            end
            ++t2
            if ttext{t2} = "0"
              t1 = ors(ttext{t2+1}) + 128
              if chr(t1) in [160,206,212,224]
                return 5
              end
              ++t2
              a5 += spc(t1)
              goto NXC
            end
            if ttext{t2} = "\"
              t1 = ors(ttext{t2})
              a5 += spc(t1)
              goto NXC
            end
            if ttext{t2} in ['a'..'z','A'..'Z']
              d1 = ors(ttext{t2})
              if "1345789" con ttext{t2+1}
                t1 = ors(ttext{t2})
              else
                if ttext{t2+1} = "2"
                  if ttext{t2} = "s"
                    t1 = 244                                /* German ss
                  else
                    t1 = ors(ttext{t2})
                  end
                else
                  return 5
                end
              end
              ++t2
            else
              --t2
              t1 = ors(ttext{t2})
            end
          else
            t1 = ors(ttext{t2})
          end
          a5 += spc(t1)
NXC:
        repeat

        loop for t2 = 1 to len(ttext)
*   adjust for backslash (\) sequence
          if ttext{t2} = "\"
            if t2 + 2 > len(ttext)
              return 5
            end
            ++t2
            if ttext{t2} in ['0'..'9'] or ttext{t2+1} in ['0'..'9']
            if ttext{t2,2} con ['0'..'9']
              if ttext{t2} in ['0'..'9']
                t1 = ors(ttext{t2+1})
                if ttext{t2} = "0"
                  t1 += 128
                end
              else
                t1 = ors(ttext{t2})
                if ttext{t2+1} = "0"
                  t1 += 128
                end
              end
              ++t2
            else
              return 5
            end
          else
            t1 = ors(ttext{t2})
          end
          a5 += spc(t1)
          if t1 = 171
            a5 -= hpar(57)
          end
        repeat


     End of 04/22/04 rewrite



      return

 ┌────────────────────────────────────────────────────┐
 │P 20a. kernttext    NEW 04/22/04 │                                                    │
 │    Purpose:  Apply kerning to ttext                │
 │                                                    │
 │    Inputs:    ttext   = word                       │
 │               c5      = current font               │
 │                                                    │
 │    Outputs:   revised ttext                        │
 │                                                    │
 └────────────────────────────────────────────────────┘

      procedure kernttext
        str tline.300
        int t1,t2,t3,t4

        if ttext = ""
          return
        end

        ttext = ttext // " "
        tline = ""
        loop for t1 = 1 to len(ttext)
          if "abcdefghijklmnopqrstuvwxyz" con ttext{t1}
            t2 = mpt
            if "abcdefghijklmnopqrstuvwxyz" con ttext{t1+1}
              t3 = mpt
              if kernmap(t2,t3) = 0
                tline = tline // ttext{t1}
              else
                if kernmap(t2,t3) = -1
                  tline = tline // ttext{t1} // "\-"
                else
                  if kernmap(t2,t3) = 1
                    tline = tline // ttext{t1} // "\!"
                  end
                end
              end
            else
              if t1 < len(ttext) - 2 and ttext{t1+1,2} = "\0" and ":=;><" con ttext{t1+3}
                if mpt < 3
                  t3 = 9         /* i
                else
                  if mpt < 5
                    t3 = 12      /* l
                  else
                    t3 = 6       /* f
                  end
                end
                if kernmap(t2,t3) = 0
                  tline = tline // ttext{t1}
                else
                  if kernmap(t2,t3) = -1
                    tline = tline // ttext{t1} // "\-"
                  else
                    if kernmap(t2,t3) = 1
                      tline = tline // ttext{t1} // "\!"
                    end
                  end
                end
              else
                tline = tline // ttext{t1}
              end
            end
          else
            if "ABCDEFGHIJKLMNOPQRSTUVWXYZ" con ttext{t1}
              t2 = mpt + 26
              if "abcdefghijklmnopqrstuvwxyz" con ttext{t1+1}
                t3 = mpt
                if kernmap(t2,t3) = 0
                  tline = tline // ttext{t1}
                else
                  if kernmap(t2,t3) = -1
                    tline = tline // ttext{t1} // "\-"
                  else
                    if kernmap(t2,t3) = -2
                      tline = tline // ttext{t1} // "\="
                    end
                  end
                end
              else
                if t1 < len(ttext) - 2 and ttext{t1+1,2} = "\0" and ":=;><" con ttext{t1+3}
                  if mpt < 3
                    t3 = 9         /* i
                  else
                    if mpt < 5
                      t3 = 12      /* l
                    else
                      t3 = 6       /* f
                    end
                  end
                  if kernmap(t2,t3) = 0
                    tline = tline // ttext{t1}
                  else
                    if kernmap(t2,t3) = -1
                      tline = tline // ttext{t1} // "\-"
                    else
                      if kernmap(t2,t3) = 1
                        tline = tline // ttext{t1} // "\!"
                      end
                    end
                  end
                else
                  tline = tline // ttext{t1}
                end
              end
            else                                              /* ffi,fi,ffl,fl,ff
              if t1 < len(ttext) - 2 and ttext{t1,2} = "\0" and ":=;><" con ttext{t1+2}
                if mpt < 3
                  t2 = 9         /* i
                else
                  if mpt < 5
                    t2 = 12      /* l
                  else
                    t2 = 6       /* f
                  end
                end
                if "abcdefghijklmnopqrstuvwxyz" con ttext{t1+3}
                  t3 = mpt
                  if kernmap(t2,t3) = 0
                    tline = tline // ttext{t1,3}
                    t1 += 2
                  else
                    if kernmap(t2,t3) = -1
                      tline = tline // ttext{t1,3} // "\-"
                      t1 += 2
                    else
                      if kernmap(t2,t3) = 1
                        tline = tline // ttext{t1,3} // "\!"
                        t1 += 2
                      end
                    end
                  end
                else
                  tline = tline // ttext{t1}
                end
              else
                tline = tline // ttext{t1}
              end
            end
          end
        repeat
        t1 = len(tline) - 1
        ttext = tline{1,t1}
      return

 ┌──────────────────────────────────────────────────────────────┐
 │P 21. spacepar                                                │
 │                                                              │
 │    Purpose:  Be sure that proper space parameters are loaded │
 │                                                              │
 │    Inputs:    c5 = font number                               │
 │                                                              │
 │    Outputs:   valid spc(.) array for this font               │
 │               font_base, font_height, zero_height            │
 │                 for this font (new 02/03/08)                 │
 │               valid kernmap(.,.) for this font               │
 │               updated value of curfont                       │
 │                                                              │
 │    Internal Variables:                                       │
 │                                                              │
 │      int bfont(4,4)  Spacepar keeps a record of past calls   │
 │                      together with the number of times       │
 │                      a particular font has been asked for.   │
 │                      If the number of fonts exceeds 4,       │
 │                      spacepar will replace the space data    │
 │                      from the memory block [bspc(.,.)]       │
 │                      least current.                          │
 │      int bspc(4,255) Four memory blocks for space data       │
 │      int bfont_specs(4,3)  4 x (font parameters) (02/03/08)  │
 │      int bkernmap(4,52,26)                                   │
 │                      Four memory blocks for backup kernmap   │
 │      int time        pseudo timer                            │
 │                                                              │
 │                                                              │
 └──────────────────────────────────────────────────────────────┘

      procedure spacepar
        str file.200
        str line.120,kfile1.80,kfile2.80
        int bfont(4,4),bspc(4,255),time
        int bfont_specs(4,3)                 /* New 02/03/08
        int bkernmap(4,52,26)
        int t1,t2,t3,t4,t5,t6,t7

        if c5 <> curfont

          font_base   = 0                    /* New 02/03/08
          font_height = 0                    /* New 02/03/08
          zero_height = 0                    /* New 02/03/08

          t2 = 1000000
          loop for t1 = 1 to 4
            if c5 = bfont(t1,1)              /* font found in reserve
              ++time
              bfont(t1,2) = time
              loop for t3 = 1 to 255
                spc(t3) = bspc(t1,t3)
              repeat

      New code 04/22/04

              loop for t3 = 1 to 52
                loop for t5 = 1 to 26
                  kernmap(t3,t5) = bkernmap(t1,t3,t5)
                repeat
              repeat

      New code 02/03/08

              font_base   = bfont_specs(t1,1)
              font_height = bfont_specs(t1,2)
              zero_height = bfont_specs(t1,3)

              curfont = c5
              return
            end
            if bfont(t1,2) < t2
              t2 = bfont(t1,2)
              t7 = t1                        /* t7 is the oldest block
            end
          repeat

      New code 02/03/08

          if box_flag = 1
            file = DISP_DISK // ":/musprint/new/xfonts/tms/fonthite"
            open [4,1] file
            t1 = c5 - 29                                        /* 1 <= t1 <= 19
            t2 = XFonts(sizenum,t1) - 50                        /* 1 <= t2 <= 90 (text font)
            --t2
            loop for t1 = 1 to t2
              getf [4]
            repeat
            getf [4] font_base font_height zero_height
            close [4]
          end
          bfont_specs(t7,1) = font_base
          bfont_specs(t7,2) = font_height
          bfont_specs(t7,3) = zero_height



      New code 03/19/04

          file = DISP_DISK // ":/musprint/new/xfonts/tms/fontspac"
          open [4,1] file
          t1 = c5 - 29                                        /* 1 <= t1 <= 19
          t2 = XFonts(sizenum,t1) - 50                        /* 1 <= t2 <= 90 (text font)
          t2 = Fspacex(t2) - 1                                /* t2 = offset in fontspac

          loop for t1 = 1 to t2
            getf [4]
          repeat

          t3 = 61
          loop for t2 = 1 to 31
            spc(t2) = 0
          repeat
          loop for t2 = 32 to 127
            if t3 = 61
              t3 = 1
              getf [4] line
            end
            spc(t2) = int(line{t3,2})
            t3 += 3
          repeat
          loop for t2 = 128 to 159
            spc(t2) = 0
          repeat
          t3 = 61
          loop for t2 = 160 to 255
            if t3 = 61
              t3 = 1
              getf [4] line
            end
            spc(t2) = int(line{t3,2})
            t3 += 3
          repeat
          close [4]
          loop for t1 = 1 to 255
            bspc(t7,t1) = spc(t1)
          repeat
          bfont(t7,1) = c5
          ++time
          bfont(t7,2) = time
          curfont = c5

      New code 04/22/04

          t1 = c5 - 29                                        /* 1 <= t1 <= 19
          t2 = XFonts(sizenum,t1) - 50                        /* 1 <= t2 <= 90 (text font)

          t3 = t2 * 4 - 3
          if t2 <= 30
            kfile1 = DISP_DISK // ":/musprint/new/xfonts/tms/stnd/kmaps/"  // kernfiles{t3,4}
            kfile2 = DISP_DISK // ":/musprint/new/xfonts/tms/stnd/kmaps2/" // kernfiles{t3,4}
          else
            if t2 <= 60
              kfile1 = DISP_DISK // ":/musprint/new/xfonts/tms/bold/kmaps/"  // kernfiles{t3,4}
              kfile2 = DISP_DISK // ":/musprint/new/xfonts/tms/bold/kmaps2/" // kernfiles{t3,4}
            else
              kfile1 = DISP_DISK // ":/musprint/new/xfonts/tms/italic/kmaps/"  // kernfiles{t3,4}
              kfile2 = DISP_DISK // ":/musprint/new/xfonts/tms/italic/kmaps2/" // kernfiles{t3,4}
            end
          end

          open [4,1] kfile1
          getf [4]
          getf [4]
          loop for t4 = 1 to 26
            getf [4] line
            t6 = 0
            loop for t5 = 5 to 55 step 2
              ++t6
              if line{t5} = " "
                kernmap(t4,t6) = 0
              else
                if line{t5} = "1"
                  kernmap(t4,t6) = -1
                else
                  if line{t5} = "0"
                    kernmap(t4,t6) = 1
                  else
                    putc kernmap file error
                    stop
                  end
                end
              end
            repeat
            getf [4] line
            if t4 = 16
              getf [4] line
              getf [4] line
            end
          repeat
          close [4]

          open [4,1] kfile2
          getf [4]
          getf [4]
          loop for t4 = 1 to 26
            getf [4] line
            t6 = 0
            loop for t5 = 5 to 55 step 2
              ++t6
              if line{t5} = " "
                kernmap(t4+26,t6) = 0
              else
                if line{t5} = "1"
                  kernmap(t4+26,t6) = -1
                else
                  if line{t5} = "2"
                    kernmap(t4+26,t6) = -2
                  else
                    putc kernmap file error
                    stop
                  end
                end
              end
            repeat
            getf [4] line
            if t4 = 16
              getf [4] line
              getf [4] line
            end
          repeat
          close [4]

          loop for t3 = 1 to 52
            loop for t5 = 1 to 26
              bkernmap(t7,t3,t5) = kernmap(t3,t5)
            repeat
          repeat
        end
      return

 ┌─────────────────────────────────────────────────────────────────┐
 │P 22. newnsp                                                     │
 │                                                                 │
 │    Purpose:  Calculate new nsp array                            │
 │                                                                 │
 │    Inputs:    scnt     = next logical record in input table     │
 │               divspq   = number of divisions per quarter note   │
 │               xmindist = minimum distance between notes (x100)  │
 │               mindist  = minimum distance between notes         │
 │                                                                 │
 │    Outputs:   new nsp array for this section                    │
 │                                                                 │
 │    Internal variables:  t1,t2,t3,t4,t5,t6                       │
 │                         mtot                                    │
 │                                                                 │
 │    Strategy:  (1) read through file until the next time         │
 │                      signature change or until the end          │
 │               (2) count number of measures where shortest       │
 │                      duration occurs                            │
 │               (3) if this represents more than xx% of the       │
 │                      outstanding measures, then this is         │
 │                      the shortest note                          │
 │               (4) otherwise, the shortest note is the           │
 │                      next one up; i.e.                          │
 │                         triplets --> regular                    │
 │                          regular --> double regular             │
 │                                                                 │
 │       nsp(32) will be space for longa                           │
 │       nsp(29) will be space for breve                           │
 │       nsp(26) will be space for whole                           │
 │       ...                                                       │
 │       nsp(5)  will be space for 128th note                      │
 │       nsp(2)  will be space for 256th note                      │
 └─────────────────────────────────────────────────────────────────┘

      procedure newnsp
        int t1,t2,t3,t4,t5,t6,t7
        int mtot
        str line.120
        t6  = scnt                 /* temporary counter in input
        loop for t1 = 1 to 33
          nsp(t1) = xmindist       /* New 12/16/03
          nsp(t1) = mindist
        repeat
        if minshort <> 0
          t1 = minshort * 4
          rem = 0                  /* sloppy code
          goto NOCALC
        end

        t2 = 100
        mtot = 0
        t7 = 0                     /* "durations found" flag (initialize at 0)
        loop
          t1 = 0
          tget [X,t6] line .t6 t1
          ++t6                     /* increment temporary counter
          line = line // pad(4)
          if line{1,4} = "/END" or line{1,4} = "/FIN"
            goto NW1
          end
          if line{1} = "$" and line con "T:" and t7 = 1
            goto NW1
          end
          if t6 > 9990
            putc
            putc                      FAULT CONDITION
            putc
            putc In searching for something, like for example, the end of a slur,
            putc AUTOSET has searched past the end of the file.  There definitely
            putc is an error in the stage2 file.  Please find and correct.
            putc
            putc Program Halted
            putc
            stop
          end
          if line{1,3} = "mea"
            ++mtot
            t4 = 0
          end
*
          if line{1} in ['A'..'G','r'] and t1 > 0  /* positive dur
            t7 = 1
            if t1 < t2
              t2 = t1                   /* new shortest note
              t3 = 0
              t4 = 0
            end
            if t1 = t2 and t4 = 0
              t4 = 1
              ++t3                      /* inc number of measures
            end
          end
        repeat

   t2 = shortest note value
   t3 = number of measures where this note occurs

NW1:
        if t7 = 0           /* No durations found (unusual case)
          mtot = 1
          t2 = 1
          t3 = 1
        end

        t5 = divspq * 16 / t2
        if t5 > 96
          t4 = 0            /* case 1: always double shortest note
        else
          if t5 > 48
            t4 = 5          /* case 2: double if less than 16%
          else
            if t5 > 24
              t4 = 8        /* case 3: double if less than 11%
            else
              t4 = 10       /* case 4: double if less than 9%
            end
          end
        end
*
        t1 = mtot / t3
        if t1 > t4
          t1 = divspq / 3
          if rem = 0
            t1 = t2 / 2
            if rem = 0
              t2 = t1 * 3
            else
              t2 *= 2
            end
          else
            t2 *= 2
          end
        end
*
        t1 = divspq * 16 / t2
   if t1 = 1, shortest note is longa
   if t1 = 2, shortest note is breve
   if t1 = 4, shortest note is whole
   if t1 = 8, shortest note is half, etc
        t2 = t1 / 3
        if rem = 0
          t1 = t2 * 2
        end

NOCALC:
        t5 = 32          /* 32 = code for longa
        t4 = 160
*
        t1 >>= 1
        loop while t1 > 0           /* i.e., if t1 started as 16th (t1 = 64), loop 6 times
          t5 -= 3
          t4 -= 20
          t1 >>= 1
        repeat
*
        if rem = 0                             /* sloppy code.  See up 100 lines for expl.
          nsp(t5) = xmindist * 10 / 9        /* New 12/16/03
          nsp(t5) = mindist * 10 / 9
        end
        if t4 > 100
          nsp(t5) = nsp(t5) * t4 / 100
        end
        nsp(t5+1) = nsp(t5) * 12 / 10
        t1 = 13
*
        loop while t5 < 31
          t4 = t5 + 3
          nsp(t4) = nsp(t5) * t1 / 10
          ++t1
          t5 = t4
          nsp(t5-1) = nsp(t5) * 9 / 10
          nsp(t5+1) = 2 * nsp(t5) - nsp(t5-3)
        repeat

     Now reduce all nsp(.) numbers by factor of 100  (12/16/03)

        loop for t1 = 1 to 33
          nsp(t1) = nsp(t1) + 50 / 100
        repeat

      return

 ┌────────────────────────────────────────────────┐
 │P 23. settime (t1)                              │
 │                                                │
 │    Purpose:  Set time signature                │
 │                                                │
 │    Inputs:    tnum = time numerator            │
 │               tden = time denominator          │
 │                p   = current x position        │
 │               oby  = 0 or 1000 (staff 0 or 1)  │
 │               spn  = space node (obj field 7)  │   01/17/04
 │                                                │
 │    Outputs:   p = new x position               │
 │               t1 = amount of empty space       │
 │                                                │
 │    Internal variables:  @e,a,dv2,dv3,dv4       │
 └────────────────────────────────────────────────┘

      procedure settime (t1)
        int t1
        jcode = tnum * 100 + tden
        putobjpar = 0

        @e = 0
        if tnum = 1 and tden = 1
          @e = 1
        end
        if tnum = 0 and tden = 0
          @e = 2
        end
*
        putc Time = ~tnum :~tden
*   set time signature
        jtype = "T"
        out = "0"
        if @e > 0
          obx = p
          oby += vpar(6)
          pcode = 1
          a = 36 + @e
          sobl(1) = "K 0 0 " // chs(a)
          jscrdat = ""
          perform putobj
          p += hpar(14)
          t1 = hpar(14) - hpar(92)
          oby -= vpar(6)
        else
          dv2 = p + hpar(16)
          if tden < 10 and tnum < 10
            dv2 = p + hpar(17)
          end
*
          obx = dv2
*
          y = vpar(4) + oby
          a = tnum
          perform number
          dv4 = dv3
          y = vpar(8) + oby
          a = tden
          perform number
          pcode = sobcnt
          jscrdat = ""
          perform putobj
          if dv3 > dv4
            dv3 = dv4
          end
          p = dv3 + hpar(18)
          t1 = hpar(18)
        end
        passback t1
      return

 ┌──────────────────────────────────────────────────────┐
 │P 24. process_section                                 │
 │                                                      │
 │    Purpose:  Set parameters for new section          │
 │                                                      │
 │    Inputs:      @b   = new key                       │
 │             divspq   = divisions per quarter         │
 │                 @e   = time signature flag           │
 │                 tnum = time numerator                │
 │                 tden = time denominator              │
 │                 @n   = set array counter (for        │
 │                         changes within measure)      │
 │                 line = "$" control code line         │
 │                                                      │
 │    Outputs:    p = new x position                    │
 │                                                      │
 │    Internal variables:  @e,a,dv2,dv3,dv4             │
 └──────────────────────────────────────────────────────┘

      procedure process_section
        int h, hh, pp, qq
        int @spn                                     /* New 01/17/04

  ┌─────────────────────────────────────────┐
  │  BEGINNING OF SECTION PROCESSING        │
  └──-──────────────────────────────────────┘


       New code for single line staff    12/18/05

        if line con "C:0"
          single_line = 1
        end


        if @n > 0

      Code changed and added 01/17/04 to fix time change bug

        if @n > 0 or outslurs <> "00000000"
          if @n = 0
            @spn = 6913
          else
            @spn = 0                      /* code for "don't use this information"
          end



          examine

          if line con "I:"
            vflag = int(line{mpt+2..})
            if vflag < 1
              vflag = 1
            end
            if vflag > 3
              vflag = 3
            end
          end
          if line con "S:"
            nstaves = int(line{mpt+2..})
            if nstaves < 1
              nstaves = 1
            end
            if nstaves > 2
              nstaves = 2
            end
          end
          if line con "C:" or line con "C1:"
            ++@n
            tv1(@n) = CLEF_CHG
            if line{mpt+2} = ":"
              ++mpt
            end
            tv2(@n) = int(line{mpt+2..})
            tv3(@n) = 0                     /* staff number
            if line con "D:" or line con "D1:" or large_clef_flag > 0  /* New 02/02/09
              tcode(@n) = "0"               /* music font
            else
              tcode(@n) = "128"             /* music font
            end
            tv5(@n) = @spn                  /* added 01/17/04
          end
          if line con "C2:"
            ++@n
            tv1(@n) = CLEF_CHG
            tv2(@n) = int(line{mpt+3..})
            tv3(@n) = 1                     /* staff number
            if line con "D2:" or large_clef_flag > 0                   /* New 02/02/09
              tcode(@n) = "0"               /* music font
            else
              tcode(@n) = "128"             /* music font
            end
            nstaves = 2
            tv5(@n) = @spn                  /* added 01/17/04
          end
          if line con "D:" or line con "D1:"
            ++@n
            tv1(@n) = DESIGNATION
            tv2(@n) = 0
            tv3(@n) = 0                     /* staff number
            tcode(@n) = ""
            if line{mpt+1} <> ":"
              ++mpt
            end
            line2 = trm(line{mpt+2..})
            tdata(@n,1) = mrt(line2)
            tv5(@n) = @spn                  /* added 01/17/04
          end
          if line con "D2:"
            ++@n
            tv1(@n) = DESIGNATION
            tv2(@n) = 0
            tv3(@n) = 1                     /* staff number
            tcode(@n) = ""
            line2 = trm(line{mpt+3..})
            tdata(@n,1) = mrt(line2)
            nstaves = 2
            tv5(@n) = @spn                  /* added 01/17/04
          end

      Another change on 05/29/05.  In this case, I am moving the keychange "K:"
      code from below the "Q:" code to above the time "T:" code.  This conforms
      with the normal way sections are introduced.  What I don't know, however,
      is whether this conflicts with some other convention, or whether the program
      code depended in some way on the old order.  Again, we must watch this
      and see if it produces strange results in the future.

          if line con "K:"
            ++@n
            tv1(@n) = AX_CHG
            tv2(@n) = int(line{mpt+2..})
            tv3(@n) = nstaves
            tcode(@n) = ""
            tv5(@n) = @spn                  /* added 01/17/04
          end

          if line con "T:"
            ++@n
            tv1(@n) = METER_CHG
            tnum = int(line{mpt+2..})
            if line con "/"
              tden = int(line{mpt+1..})
            else
              return 6
            end
            tv2(@n) = 100 * tnum + tden
            tv3(@n) = nstaves
            tcode(@n) = ""
            tv5(@n) = @spn                  /* added 01/17/04
          end
          if line con "Q:"
            ++@n
            tv1(@n) = DIV_CHG
            tv2(@n) = int(line{mpt+2..})
            tv3(@n) = 0
            tcode(@n) = ""
            tv5(@n) = @spn                  /* added 01/17/04
          end

      Moving this code to above the time "T:" code (05/29/05)

          if line con "K:"
            ++@n
            tv1(@n) = AX_CHG
            tv2(@n) = int(line{mpt+2..})
            tv3(@n) = nstaves
            tcode(@n) = ""
            tv5(@n) = @spn                  /* added 01/17/04
          end


          /* old system; better to use print suggestions

          if line con "P:"
            mindist = int(line{mpt+2..}) * notesize / 16
          end
          return
        end
*
        spn = 6913

        "P:" is the old system; it's actually better to use the
        new system of print suggestions to change note spacing

        if line con "P:"
          mindist = int(line{mpt+2..}) * notesize / 16
        end

        if line con "I:"
          vflag = int(line{mpt+2..})
          if vflag < 1
            vflag = 1
          end
          if vflag > 3
            vflag = 3
          end
        end
        if line con "S:"
          nstaves = int(line{mpt+2..})
          if nstaves < 1
            nstaves = 1
          end
          if nstaves > 2
            nstaves = 2
          end
        end
        if line con "D2:"
          nstaves = 2
        end

    (1) clef

        if line con "C:" or line con "C1:" or line con "C2:"
          i = 0
          h = 0
          if line con "C:" or line con "C1:"
            if line{mpt+1} = ":"
              i = mpt + 2
            else
              i = mpt + 3
            end
          end
          if line con "C2:"
            h = mpt + 3
            nstaves = 2
          end
          if i*h = 0      /* Case1: only one clef designator
            if i > 0
              k = 1
            else
              i = h
              k = 2
            end
            clef(k) = int(line{i..})

       Special code for single line instruments 12/18/05

            if single_line = 1
              clef(1) = 4
            end

            perform zjcline (k)
            if p > 0
              p -= hpar(37)
            end
            p += hpar(5)
*   print clef
            obx = p
            oby = 5 - j * notesize
            oby = (k - 1) * 1000 + oby
            if single_line = 0                   /* New condition 12/18/05
              perform putclef (k)
            end
          else            /* Case2: two clef designators
            k = 1
            clef(k) = int(line{i..})
            perform zjcline (k)
            if p > 0
              p -= hpar(37)
            end
            p += hpar(5)
*   print clef on staff 1
            obx = p
            oby = 5 - j * notesize
            perform putclef (k)
            k = 2
            clef(k) = int(line{h..})
            perform zjcline (k)
*   print clef on staff 2
            obx = p
            oby = 5 - j * notesize
            oby += 1000
            perform putclef (k)
          end
*   advance horizontal pointer
          p += hpar(8)
          pp = hpar(8) - hpar(86)
          loop for h = 1 to MAX_STAFF
            loop for hh = 1 to 45
              emptyspace(h,hh) = pp
            repeat
          repeat
        end

    (2) key signature

        if line con "K:"
          @b = int(line{mpt+2..})
          if line{sub} = "("                  /* new code 08/23/06
            if line{sub+1} = "+"
              h = int(line{sub+2..})
            else
              h = int(line{sub+1..})
            end
          else
            h = 0
          end
          hh = 1
          perform key_change (@b, key, nstaves, hh, h)    /* fifth variable added 08/23/06

          /* this sets key = @b and resets claveax(.), emptyspace(.,.)  etc.

        end

    (3) divisions per quarter

        if line con "Q:"
          olddivspq = int(line{mpt+2..})
        end

    (4) time word

        if line con "D:" or line con "D1:" or line con "D2:"
          a1 = 6913
          if line not_con "T:"
            a1 = 1

     f4 is set when a directive is placed with spn = 1.  This
     directive takes its position from the next controlling
     object in the part.  Therefore, it must not be followed
     by a multiple rest.

            f4 = 1
          end
          if line con "D:"
            temp3 = trm(line{mpt+2..})
            temp3 = mrt(temp3)
            oby = 0 - tword_height * vpar(1)
            ++outpnt
            tput [Y,outpnt] J D 5 ~p  ~oby  1 ~a1  0 0
            ++outpnt
            tput [Y,outpnt] W 0 0 ~dtivfont  ~temp3
          end
          if line con "D1:"
            temp3 = trm(line{mpt+2..})
            temp3 = mrt(temp3)
            oby = 0 - tword_height * vpar(1)
            ++outpnt
            tput [Y,outpnt] J D 5 ~p  ~oby  1 ~a1  0 0
            ++outpnt
            tput [Y,outpnt] W 0 0 ~dtivfont  ~temp3
          end
          if line con "D2:"
            temp3 = trm(line{mpt+2..})
            temp3 = mrt(temp3)
            oby = 0 - tword_height * vpar(1)
            oby += 1000
            ++outpnt
            tput [Y,outpnt] J D 5 ~p  ~oby  1 ~a1  0 0
            ++outpnt
            tput [Y,outpnt] W 0 0 ~dtivfont  ~temp3
          end
        end

    (5) time signature (also new note spacing calculations)

        if line con "T:"
          tnum = int(line{mpt+2..})
          if line con "/"
            tden = int(line{mpt+1..})
          else
            return 6
          end
          oby = 0
          pp = p
          loop for hh = 1 to nstaves
            p = pp
            perform settime (h)

        Actually, we will set emptyspace to hpar(29), the mimimum space
        space allowed before an accidental.  This way, no note-type
        objects will be able to crowd the time signature.  If this
        works, we can remove the code that returns the value (h) from
        settime.  (We actually shouldn't be interested in this value
        anyway, because we do NOT want to get too close to the time
        signature.)

            loop for qq = 1 to 45
              emptyspace(hh,qq) = min_space            /* replaces hpar(29)   11/19/07
            repeat
            oby += 1000
          repeat
          if tnum = 1 and tden = 1
            tnum = 4
            tden = 4
          end
          if tnum = 0 and tden = 0
            tnum = abflg
            tden = 2
          end

    determine note spacing
    ----------------------

          divspq = olddivspq
          perform newnsp
        end
      return

  ┌───────────────────────────────┐
  │  END OF SECTION PROCESSING    │
  └───────────────────────────────┘

 ┌──────────────────────────────────────────────────────┐
 │P 25. key_change (newkey, oldkey, nstaves, t1, t2)    │
 │                                                      │
 │    Purpose:  Typeset a key change                    │
 │                                                      │
 │    Inputs:   int  newkey    new key                  │
 │              int  oldkey    old key                  │
 │              int  nstaves   number of staves         │
 │              int  t1        operation code           │
 │                               1 = change emptyspace  │
 │                               0 = don't do it        │
 │              int  t2        part of new key in       │
 │                               parenthesis  08/23/06 │                                                      │
 │    Global variables:                                 │
 │                                                      │
 │              sobcnt         subobject counter        │
 │              p              x position pointer       │
 │              x              actual x-coordinate      │
 │              y              actual y-coordinate      │
 │              z              font number              │
 │              obx            object x-coordinate      │
 │              oby            object y-coordinate      │
 │              clef(.)        current clef             │
 │              measax(.,.)    current measure ax array │
 │              claveax(.)     global ax array          │
 │              jtype          object type              │
 │              jcode          object code              │
 │              pcode          number of sub objects    │
 │              out            ASCII string             │
 │                                                      │
 │    Outputs:    p = new x position                    │
 │                emptyspace(.,.) changed (if t1 = 1)   │
 │                                                      │
 └──────────────────────────────────────────────────────┘

      procedure key_change (newkey, oldkey, nstaves, t1, t2)    /* t2 added 08/23/06
        int newkey, oldkey, nstaves
        int save_oldkey                          /* added 11/05/05
        int sy
        int a, m, h, i, j, k
        int hh
        int t1,t2,t3                             /* t2,t3 added 08/23/06
        int klave,sklave
        int tenor
        int m1,m2,m3,m4,m5,m6                    /* added 08/23/06

        getvalue newkey, oldkey, nstaves, t1, t2

        if t2 <> 0                               /* magic numbers for editorial [] 08/23/06
          m1 = (2 * notesize + 3 / 6)
          m2 = (4 * notesize + 3 / 6)
          m3 = (7 * notesize + 3 / 6)
          m4 = notesize + 3 / 6
          m5 = (5 * notesize + 3 / 6)
          m6 = notesize
        end

        t3 = newkey                  /* added 08/23/06
        newkey = newkey + t2         /* added 08/23/06

     This code added 11/26/06 to allow reprint of existing key signature

        if newkey = oldkey and key_reprint_flag > 0
          oldkey = 0
        end
                 End of 11/26/06 addition



     New code.  10/15/07.  It used to be the case that a non key
     change in an orchestra part (such as horns) simply returned
     at this point.  No i-file entry was generated because none was
     needed.  The problem created by this was that if the mskpage
     program was looking for a key change node (because other parts
     had one) and didn't find one, this could cause a misalignment
     of control node.  It turns out that the program crashed only
     when the key change came at the end of a line, so nothing was
     done about it.  (The bug was rare, and difficult to identify).
     The advent of justification made the bug more likely to occur,
     and it did (once too often).  So I decided on this fix, namely:
 
     From now on, all key changes will generate a "J K" node, even
     if there is none to be printed.  In this case, the node will
     have no sub-objects and will therefore be "silent."  This seems
     to have caused no other problems with the programs.


        if newkey = oldkey
          loop for hh = 1 to nstaves
            putobjpar = 0
            sobcnt = 0
            oby = 0
            obx = p
            x = obx
            jtype = "K"
            jcode = newkey
            pcode = 0
            out = "0"
            oby = (hh - 1) * 1000
            jscrdat = ""
            perform putobj
          repeat
          return
        end

     End of 10/15/07 addition

                                                               



     New code.  11/02/07.   Another situation has come up, which
     I believe can be dealt with here.  In the case where the timpani
     plays on the notes B-flat and F, the notation shows these two
     pitches without a key signature.  In order to make this work, the
     encoder used the pitches B-natural and F, and a key signature of
     0 (no sharps or flats).  This of course would wreck havoc in a
     midi file.  It would be far better to encode the key as -1 (one
     flat) and then encode the pitches B-flat and F, as they would
     actually sound.  The problem with this is that the key signature
     would appear at the beginning of every line.  We need to have
     a way to suppress this.  I propose a new global flag, suppress_key,
     which can be set by the "k" global suggestion.  The following
     code deals with this situation.

        if suppress_key > 0
          save_oldkey = oldkey
          loop for hh = 1 to nstaves

*   set up new global accidentals for claveax

            oldkey = newkey
            loop for i = 1 to 50
              claveax(i) = 0
            repeat
            h = newkey
            if h > 0
              k = 4
              loop for i = 1 to h
                loop for a = k to 50 step 7
                  claveax(a) = 2
                repeat
                k += 4
                if k > 7
                  k -= 7
                end
              repeat
            end
            if h < 0
              h = 0 - h
              k = 7
              loop for i = 1 to h
                loop for a = k to 50 step 7
                  claveax(a) = 3
                repeat
                k -= 4
                if k < 1
                  k += 7
                end
              repeat
            end
            oldkey = save_oldkey

            putobjpar = 0
            sobcnt = 0
            oby = 0
            obx = p
            x = obx
            jtype = "K"
            jcode = 0
            pcode = 0
            out = "0"
            oby = (hh - 1) * 1000
            jscrdat = ""
            perform putobj
          repeat

          loop for i = 1 to 50
            loop for h = 1 to 4                  /* 06/04/08 was 3
              measax(h,i) = claveax(i)
            repeat
          repeat
          oldkey = newkey                        /* moved 11/05/05
          passback  oldkey

          return
        end

     End of 11/02/07 addition

                                                               

        putobjpar = 0

        save_oldkey = oldkey                     /* added 11/05/05
        loop for hh = 1 to nstaves
          sobcnt = 0
          oby = 0
          i = clef(hh) / 10
          klave = rem - 1 * 2
          i /= 3
          k = 2 - rem * 3
          klave -= k
          obx = p
          x = obx
          tenor = 0
          if clef(hh) = 12
            tenor = 2
          end
*   sharps
          if newkey > 0
*     cancellations?
            sy = y
            sklave = klave
            if oldkey > newkey
              loop for j = 1 to newkey
                y += zak(1,j)
                klave += zak(1,j)
              repeat
              h = oldkey - newkey
              m = 1 + tenor
              perform cancelsig (m,j,h,klave)
            end
            if oldkey < 0
              h = 0 - oldkey
              y += vpar(4)
              klave += 4
              j = 0
              m = 2
              perform cancelsig (m,j,h,klave)
            end
            y = sy
            klave = sklave
*   set new key
            kscrdat = ""
            if t2 = 0
              loop for j = 1 to newkey
                z = 63
                if tenor = 0 or klave >= 0
                  y = klave + 20 * notesize / 2 - vpar20
                else
                  y = klave + 27 * notesize / 2 - vpar20    /* exception for tenor clef
                end
                perform subj
                y += zak(1,j)
                klave += zak(1,j)
                x += hpar(9)
              repeat
            else

       This code added 08/23/06 to deal with editorial additions of sharps

              if t2 > 0
                loop for j = 1 to t3
                  z = 63
                  if tenor = 0 or klave >= 0
                    y = klave + 20 * notesize / 2 - vpar20
                  else
                    y = klave + 27 * notesize / 2 - vpar20  /* exception for tenor clef
                  end
                  y = klave + 20 * notesize / 2 - vpar20
                  perform subj
                  klave += zak(1,j)
                  x += hpar(9)
                repeat
                loop for j = t3 + 1 to newkey
                  x += m1                                   /* magic number
                  z = 67
                  if tenor = 0 or klave >= 0
                    y = klave + 20 * notesize / 2 - vpar20
                  else
                    y = klave + 27 * notesize / 2 - vpar20  /* exception for tenor clef
                  end
                  y = klave + 20 * notesize / 2 - vpar20
                  perform subj
                  x += m2                                   /* magic number
                  z = 63
                  perform subj
                  x += m3                                   /* magic number
                  z = 68
                  perform subj
                  klave += zak(1,j)
                  x += (hpar(9) - m3)                       /* magic number
                repeat
              end

         End of 08/23/06 addition
            end
          end
*   no sharps or flats
          if newkey = 0
*     cancellations?
            j = 0
            if oldkey > 0
              h = oldkey
              m = 1 + tenor
              perform cancelsig (m,j,h,klave)
            end
            if oldkey < 0
              h = 0 - oldkey
              m = 2
              y += vpar(4)
              klave += 4
              perform cancelsig (m,j,h,klave)
            end
          end
*   flats
          if newkey < 0
*     cancellations?
            sy = y
            sklave = klave
            if oldkey < newkey
              h = 0 - newkey
              y += vpar(4)
              klave += 4
              loop for j = 1 to h
                y += zak(2,j)
                klave += zak(2,j)
              repeat
              h = newkey - oldkey
              m = 2
              perform cancelsig (m,j,h,klave)
            end
            if oldkey > 0
              h = oldkey
              j = 0
              m = 1 + tenor
              perform cancelsig (m,j,h,klave)
            end
            y = sy + vpar(4)
            klave = sklave + 4
*   set new key
            kscrdat = ""
            if t2 = 0
              h = 0 - newkey
              loop for j = 1 to h
                z = 65
                y = klave + 20 * notesize / 2 - vpar20

    Code added 09/13/06 to fix flats in soprano clef

                if y > vpar(8)
                  y -= vpar(7)
                end

                perform subj
                y += zak(2,j)
                klave += zak(2,j)
                x += hpar(11)
              repeat
            else

       This code added 08/23/06 to deal with editorial additions of flats

              if t2 < 0
                t3 = 0 - t3
                h = 0 - newkey
                loop for j = 1 to t3
                  z = 65
                  y = klave + 20 * notesize / 2 - vpar20

    Code added 09/13/06 to fix flats in soprano clef

                  if y > vpar(8)
                    y -= vpar(7)
                  end

                  perform subj
                  klave += zak(2,j)
                  x += hpar(9)
                repeat
                loop for j = t3 + 1 to h
                  x += m4                                   /* magic number
                  z = 67
                  y = klave + 20 * notesize / 2 - vpar20

    Code added 09/13/06 to fix flats in soprano clef

                  if y > vpar(8)
                    y -= vpar(7)
                  end

                  perform subj
                  x += m5                                   /* magic number
                  z = 65
                  perform subj
                  x += m6                                   /* magic number
                  z = 68
                  perform subj
                  klave += zak(2,j)
                  x += (hpar(11) - m6)                      /* magic number
                repeat
              end

         End of 08/23/06 addition
            end
          end
*   Write out object and subobjects
          jtype = "K"
          jcode = newkey
          pcode = sobcnt
          out = "0"
          oby = (hh - 1) * 1000
          jscrdat = ""
          perform putobj
*
          if newkey = 0 and oldkey = 0
            i = hpar(13)
            if t1 = 1
              loop for j = 1 to 45
                emptyspace(hh,j) += i
              repeat
            end
          else
            i = hpar(12)
            if t1 = 1
              loop for j = 1 to 45
                emptyspace(hh,j) = i
              repeat
            end
          end

          if hh = nstaves
            p = x + i
          end
*   set up new global accidentals for claveax
          oldkey = newkey
          loop for i = 1 to 50
            claveax(i) = 0
          repeat
          h = newkey
          if h > 0
            k = 4
            loop for i = 1 to h
              loop for a = k to 50 step 7
                claveax(a) = 2
              repeat
              k += 4
              if k > 7
                k -= 7
              end
            repeat
          end
          if h < 0
            h = 0 - h
            k = 7
            loop for i = 1 to h
              loop for a = k to 50 step 7
                claveax(a) = 3
              repeat
              k -= 4
              if k < 1
                k += 7
              end
            repeat
          end
          oldkey = save_oldkey                   /* changed 11/05/05 (was oldkey = newkey)
        repeat
        loop for i = 1 to 50
          loop for h = 1 to 4                    /* 06/04/08 was 3
            measax(h,i) = claveax(i)
          repeat
        repeat
        oldkey = newkey                          /* moved 11/05/05
        passback  oldkey
      return

 ┌──────────────────────────────────────────────────────┐
 │P 26. display_ts                                      │
 │                                                      │
 │    Purpose:  Display parameters in ts(.,.) array     │
 │                                                      │
 └──────────────────────────────────────────────────────┘

      procedure display_ts
        str temp.TSR_LENG
        int t1,t2,t3

        putc   TYPE  DIV CLAV  AX  NTYP  DOT TPLE VLOC SPAC STEM BMFG BMCD      ...
        putc SUPF SLUR SUB1 SUB2 YSH  SRT2 TEXT PASS BTIE NDUR DINC MULT

        loop for t2 = 1 to TS_SIZE
          putc .t2w4 ~t2 ...
        repeat
        putc
        putc   ...
        loop for t2 = 1 to 6
          putc ==== ==== ==== ==== ==== ==== ...
        repeat
        putc
        loop for t1 = 1 to sct
          loop for t2 = 1 to TS_SIZE
            putc .t2w4 ~ts(t1,t2) ...
          repeat
          putc
        repeat
DTS1:
        putc
        putc Type a number (pointer value in col 34) to see the tsr string for an item.
        t3 = 0
        getc t3
        if t3 = 0
          return
        end
        temp = tsr(t3)
        putc    TSR string at pointer ~t3
        putc Item  byte1  byte2  byte3  byte4
        loop for t1 = 1 to (TSR_LENG >> 2)
          putc .w4 ~t1 ...
          loop for t2 = -3 to 0 step 1
            t3 = ors(temp{t1*4+t2})
            putc .w7x ~t3 ...
          repeat
          putc
        repeat
        goto DTS1
      return

 ┌────────────────────────────────────────────────────────────────────┐
 │P 27. zjcline (staff)                                               │
 │                                                                    │
 │    Purpose:  Compute values of z, j, and cline from clef           │
 │                                                                    │
 │    Inputs:   staff    = staff number (1 or 2)                      │
 │              clef(.)  = clef flag                                  │
 │                                                                    │
 │    Outputs:  z        = clef font                                  │
 │              j        = vertical postion of clef                   │
 │              cline(.) = location of middle C                       │
 └────────────────────────────────────────────────────────────────────┘

      procedure zjcline (staff)
        int g,h,i,k,m
        int staff
        getvalue staff
        i = clef(staff) / 10
        j = 6 - rem
        k = i / 3
        h = rem
        if rem = 0
          z = 33
        else
          z = 34 + h
        end
        m = j * 2 + 20
        g = 0
        if k > 0
          if k = 1
            g = 7
          else
            g = -7
          end
        end
        cline(staff) = h - 1 * 4 + m + g

      return

 ┌───────────────────────────────────────────────────────┐
 │P 28. putclef (staff)                                  │
 │                                                       │
 │    Purpose:  write clef sign to intermediate file     │
 │                                                       │
 │    Inputs:   staff   = staff number (1 or 2)          │
 │              clef(.) = clef code                      │
 │              obx     = x offset                       │
 │              oby     = y offset                       │
 │              z       = clef font                      │
 └───────────────────────────────────────────────────────┘

      procedure putclef (staff)
        int staff
        int g,h,i,k,m
        getvalue staff
        i = clef(staff) / 10
        k = i / 3
        h = rem
        jtype = "C"
        jcode = clef(staff)
        out = "0"
        kscrdat = ""
        if h = 0
          x = obx
          y = oby
          perform subj
          ++z
          perform subj
          if k = 1
            x = obx + hpar(52)
            y = oby + vpar(23)
            z = 234
            perform subj
          end
          pcode = sobcnt
        else
          pcode = z
        end
        putobjpar = 0
        jscrdat = ""
        perform putobj
      return

 ┌─────────────────────────────────────────────────────────────────┐
 │P 29. rotate_array (t1,t2)                                       │
 │                                                                 │
 │    Purpose:  Move ts array elements at t2 to t1 position.       │
 │              Rotate all other elements down one                 │
 │                                                                 │
 │    Inputs:   t1    = top of rotation                            │
 │              t2    = bottom of rotation (t2 > t1)               │
 │                                                                 │
 └─────────────────────────────────────────────────────────────────┘

      procedure rotate_array (t1,t2)
        int temp(TS_SIZE)
        int t1,t2,t3,t4
        getvalue t1,t2
        if t2 = t1
          return
        end
        if t2 < t1
          putc Program error at rotate
          examine
          stop
        end
        loop for t3 = 1 to TS_SIZE
          temp(t3) = ts(t2,t3)          /* create hole at the bottom (save bottom)
        repeat
        loop for t4 = t2 to t1+1 step -1    /* loop in backwards order
          loop for t3 = 1 to TS_SIZE
            ts(t4,t3) = ts(t4-1,t3)     /* copy each row from the one above it
          repeat
        repeat
        loop for t3 = 1 to TS_SIZE
          ts(t1,t3) = temp(t3)          /* store bottem piece at top
        repeat
      return

 ┌─────────────────────────────────────────────────────────────────┐
 │P 30. get_topbottom (t1,t2,t3)                                   │
 │                                                                 │
 │    Purpose:  If t1 points to a ts row element which is a note   │
 │              head, then t2 will point to the ts row element     │
 │              which is the top of the chord, and t3 will point   │
 │              to the ts row element which is the bottom of the   │
 │              chord                                              │
 │                                                                 │
 │    Inputs:   t1    = index to ts row element                    │
 │                                                                 │
 │    Outputs:  t2    = index to top of chord                      │
 │              t3    = index to bottom of chord                   │
 │                                                                 │
 │    Note:  Do not call this procedure before GLOBAL_XOFF is set  │
 │                                                                 │
 └─────────────────────────────────────────────────────────────────┘

      procedure get_topbottom (t1,t2,t3)
        int t1,t2,t3,t4
        getvalue t1
        t4 = ts(t1,GLOBAL_XOFF)
        if t4 > INT10000
          t2 = t4 / INT10000
          t3 = rem
        else
          t4 = ts(t1+1,GLOBAL_XOFF)
          if t4 > INT10000
            t2 = t4 / INT10000
            t3 = rem
          else
            t2 = t1
            t3 = t1
          end
        end
        passback t2,t3
      return


   
     PROCEDURES FOR PSEUDO-TYPESETTING
   



 ┌─────────────────────────────────────────────────────────────────┐
 │P 31. ps_setchord (p1,p2,p3)                                     │
 │                                                                 │
 │    Purpose:  Add a chord to the simultaneity                    │
 │                                                                 │
 │    Inputs:   p1 = pass number (chord number)                    │
 │              p2 = second chord number (for unisons) or 100      │
 │              p3 = initialize parameter (0 = initialize)         │
 │                                                                 │
 │    Outputs:  p3 = initialize parameter (1 = don't initialize)   │
 │              printpos(.) = print position for this chord        │
 │                                                                 │
 │    Method:   construct the left boundary of the new chord.      │
 │              Move the chord to the right until it bumps         │
 │              with previous chords.                              │
 │                                                                 │
 │    Output:   when a note for a chord is set, ndata(*,PASS)      │
 │              for that note is set to zero.                      │
 │                                                                 │
 │              printpos(p1) and maybe printpos(p2)                │
 │                                                                 │
 │                                                                 │
 │                                                                 │
 └─────────────────────────────────────────────────────────────────┘

      procedure ps_setchord (p1,p2,p3)
        int a,b,c,d,e,x
        int aa,bb,cc,dd
        int tr(2,45),tl(2,45)
        int pseudo_tr(2,45)
        int pseudo_tl(2,45)
        int f,g,h,i,j,k
        int ff,gg,hh
        int p1, p2, p3
        int ps_width
        int stem_up_flag
        int stem_down_flag


        getvalue p1,p2,p3

        if p3 = 0
          p3 = 1
          x = 10000
        else
          x = 0
        end
        passback p3

        putc Calling ps_setchord  pass = ~p1   pass2 = ~p2
        putc


        ff = 0
        hh = 0

        loop for j = 1 to 45
          tl(1,j) = 200
          tr(1,j) = -200
          pseudo_tr(1,j) = -200
          pseudo_tl(1,j) = 200
          tl(2,j) = 200
          tr(2,j) = -200
          pseudo_tr(2,j) = -200
          pseudo_tl(2,j) = 200
        repeat

        stem_up_flag    = 0
        stem_down_flag  = 0
        repeater_case   = 0
        c = 100
        loop for i = 1 to pcnt
          if ndata(i,PS_PASS) = p1 or ndata(i,PS_PASS) = p2
            b = ndata(i,PS_XPOS)
            a = ndata(i,PS_PITCH)

            putc set note ~i   pitch = ~ndata(i,PS_PITCH)   ...
            putc shift = ~ndata(i,PS_XPOS)

            if a = 100
              ndata(i,PS_PASS) = 0
              return
            end

            if c = 100
              c = ndata(i,PS_STAFF) + 1       /* staff number
              d = ndata(i,PS_COLOR)
              if d < 3
                ps_width = hpar(82)
              else
                if d = 3
                  ps_width = hpar(83)
                else
                  ps_width = hpar(84)
                end
              end
              if ndata(i,PS_NSIZE) = CUESIZE
                ps_width = ps_width * 8 / 10
              end
            end

            if bit(0,ndata(i,PS_STEM)) = UP         /* stem up
              if b = 0
                if tl(c,a) > 0
                  tl(c,a) = 0
                end
                if tl(c,a+1) > hpar(95)
                  tl(c,a+1) = hpar(95)
                end
                if pseudo_tl(c,a) > 0
                  pseudo_tl(c,a) = 0
                end
                if pseudo_tl(c,a+1) > 0
                  pseudo_tl(c,a+1) = 0
                end
                if tr(c,a) < ps_width - hpar(95)
                  tr(c,a) = ps_width - hpar(95)
                end
                if tr(c,a+1) < ps_width
                  tr(c,a+1) = ps_width
                end
                if pseudo_tr(c,a) < ps_width
                  pseudo_tr(c,a) = ps_width
                end
                if pseudo_tr(c,a+1) < ps_width
                  pseudo_tr(c,a+1) = ps_width
                end
              else
                dd = ps_width << 1 - hpar(90)
                if tr(c,a) < dd - hpar(95)
                  tr(c,a) = dd - hpar(95)
                end
                if tr(c,a+1) < dd
                  tr(c,a+1) = dd
                end
                if pseudo_tr(c,a) < dd + hpar(49)
                  pseudo_tr(c,a) = dd + hpar(49)
                end
                if pseudo_tr(c,a+1) < dd + hpar(49)
                  pseudo_tr(c,a+1) = dd + hpar(49)
                end
              end
              if ff = 0
                ff = a + 8                     /* 8 = length of stem
              end
              stem_up_flag |= ndata(i,PS_STEM) >> 2
            else
              if b = 0
                if tr(c,a) < ps_width - hpar(95)
                  tr(c,a) = ps_width - hpar(95)
                end
                if tr(c,a+1) < ps_width
                  tr(c,a+1) = ps_width
                end
                if pseudo_tr(c,a) < ps_width
                  pseudo_tr(c,a) = ps_width
                end
                if pseudo_tr(c,a+1) < ps_width
                  pseudo_tr(c,a+1) = ps_width
                end
                if tl(c,a) > 0
                  tl(c,a) = 0
                end
                if tl(c,a+1) > hpar(95)
                  tl(c,a+1) = hpar(95)
                end
                if pseudo_tl(c,a) > 0
                  pseudo_tl(c,a) = 0
                end
                if pseudo_tl(c,a+1) > 0
                  pseudo_tl(c,a+1) = 0
                end
              else
                if tl(c,a) > hpar(90) - ps_width
                  tl(c,a) = hpar(90) - ps_width
                end
                if tl(c,a+1) > hpar(90) - ps_width + hpar(95)
                  tl(c,a+1) = hpar(90) - ps_width + hpar(95)
                end
                if pseudo_tl(c,a) > hpar(90) - ps_width - hpar(49)
                  pseudo_tl(c,a) = hpar(90) - ps_width - hpar(49)
                end
                if pseudo_tl(c,a+1) > hpar(90) - ps_width - hpar(49)
                  pseudo_tl(c,a+1) = hpar(90) - ps_width - hpar(49)
                end
              end
              if hh = 0
                hh = a - 1
              end
              stem_down_flag |= ndata(i,PS_STEM) >> 2
            end
            repeater_case |= bit(1,ndata(i,PS_STEM))
            if ndata(i,PS_PASS) = p1
              ndata(i,PS_PASS) = 0
            end
            if ndata(i,PS_PASS) = p2
              ndata(i,PS_PASS) = 0
            end
          end
        repeat
        if hh > 45
          hh = 45
        end
        if ff > 0               /*  put in stem up restraints
          e = ps_width - hpar(90)          /* OLD ps_width - hpar(85)
          d = ps_width                     /* OLD ps_width + hpar(85)
          if repeater_case = 1
            aa = e - hpar(98)
            bb = d + hpar(98)
          else
            aa = e
            bb = d
          end
          if stem_up_flag > 0
            if stem_up_flag > 2
              ff += stem_up_flag - 2 << 1
            end
            dd = d + hpar(26)
          else
            dd = d
          end
          if ff > 45
            ff = 45
          end
          loop for i = ff - 6 to ff
            if tl(c,i) > aa
              tl(c,i) = aa
            end
            if tr(c,i) < bb
              tr(c,i) = bb
            end
            if pseudo_tr(c,i) < dd
              pseudo_tr(c,i) = dd
            end
          repeat
          loop for i = a + 2 to ff - 7
            if tl(c,i) > e
              tl(c,i) = e
            end
            if tr(c,i) < d
              tr(c,i) = d
            end
          repeat
        end
        if hh > 0               /*  put in stem down restraints
          a = a - 7
          if stem_down_flag > 0
            if stem_down_flag > 2
              a -= stem_down_flag - 2 << 1
            end
            dd = hpar(90) + hpar(26)
          else
            dd = hpar(90)
          end
          if a < 1
            a = 1
          end

       Fixing the left border on stems down with repeaters
       06/04/08   plus bug correction  11/23/09

#if XPOS_FIXED
          loop for i = a + 4 to hh
            if tl(c,i) > 0             /* aa
              tl(c,i) = 0              /* aa
            end
            if tr(c,i) < hpar(90)      /* bb
              tr(c,i) = hpar(90)       /* bb
            end
            if pseudo_tr(c,i) < dd
              pseudo_tr(c,i) = dd
            end
          repeat
#else
          loop for i = a + 4 to hh
            if tl(c,i) > 0   /* aa
              tl(c,i) = 0    /* aa
            end
            if tr(c,i) < bb
              tr(c,i) = bb
            end
            if pseudo_tr(c,i) < dd
              pseudo_tr(c,i) = dd
            end
          repeat
#endif

          if repeater_case = 1
            aa = 0 - hpar(98)
            bb = hpar(90) + hpar(98)
          else
            aa = 0
            bb = hpar(90)
          end

          loop for i = a to a + 3           /* 4 is magic number
            if tl(c,i) > aa                 /* Repeaters only at bottom
              tl(c,i) = aa
            end
            if tr(c,i) < bb
              tr(c,i) = bb
            end
            if pseudo_tr(c,i) < dd
              pseudo_tr(c,i) = dd
            end
          repeat
        end

        if x = 10000
          loop for i = 1 to 45
            gr(c,i) = tr(c,i)
            gl(c,i) = tl(c,i)
            pseudo_gr(c,i) = pseudo_tr(c,i)
          repeat
          x = 0                   /* amount shifted to the right
        else
          ff = 1000
          loop for i = 1 to 45
            gg = 1000 - gr(c,i) + tl(c,i) - 5
            if gg < ff
              ff = gg
            end
          repeat
          x = 1000 - ff           /* amount shifted to the right
          loop for i = 1 to 45
            gg = x + tr(c,i)
            if gg > gr(c,i) and tr(c,i) <> -200
              gr(c,i) = gg
            end
            gg = x + pseudo_tr(c,i)
            if gg > pseudo_gr(c,i) and pseudo_tr(c,i) <> -200
              pseudo_gr(c,i) = gg
            end
            gg = x + tl(c,i)
            if gg < gl(c,i)
              gl(c,i) = gg
            end
          repeat
        end

        loop for j = 1 to 45
          if pseudo_gl(1,j) > pseudo_tl(1,j)
            pseudo_gl(1,j) = pseudo_tl(1,j)
          end
          if pseudo_gl(2,j) > pseudo_tl(2,j)
            pseudo_gl(2,j) = pseudo_tl(2,j)
          end
        repeat

        loop for j = 1 to 1
          putc Left     Right    Pseudo Left    Pseudo Right
          loop for i = 45 to 1 step -1
            putc .w5 ~gl(j,i)  ~gr(j,i)   ~pseudo_gl(j,i)    ~pseudo_gr(j,i)
          repeat
          putc ═════════════════════════════════════
        repeat
        getc

        printpos(p1) = x
        if p2 <> 100
          printpos(p2) = x
        end
        putc print position equals ~x
        putc
      return

 ┌──────────────────────────────────────────────────────────────────────────────┐
 │P 32. guessbeam (slope, t12)                                                  │
 │                                                                              │
 │                                                                              │
 │    Purpose:  Make a guess about the position of a beam                       │
 │                                                                              │
 │    Inputs:   int  c6            = number of notes under beam                 │
 │              int  mf(.)         = y-position of note                         │
 │              int  beamcode(.)   = beam code                                  │
 │              int  stem          = stem direction (UP/DOWN)                   │
 │              int  c5            = size: 0 = regular; 1 = small               │
 │                                                                              │
 │    Outputs:  int slope  = BHPAR1 * slope of beam                             │
 │              int t12    = end point of first stem (relative to top of staff) │
 │                                                                              │
 │    Internal variables:  beamfy = y coordinate of first note under beam       │
 │                         vrange = vertical range of note set                  │
 │                         zstaff = top of staff line                           │
 │                          slope = slope of beam                               │
 │                           ypiv = temporary variable                          │
 │                        (x1,y1) = temporary coordinates                       │
 │                        (x2,y2) = temporary coordinates                       │
 └──────────────────────────────────────────────────────────────────────────────┘

      procedure guessbeam (slope, t12)
        int t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12
        int zstaff,ypiv,slope
        int x1,x2,y1,y2,vrange,beamfy
        int xf(100)
        int beamh,beamt,bthick
        int beamtype
        int loopcnt
*
        if c5 = 0
          beamh = bvpar(16)
          beamt = bvpar(32)
          bthick = vpar(2) * 6 / 14
        else
          beamh = bvpar(16) * 4 / 5
          beamt = bvpar(32) * 4 + 3 / 5
          bthick = vpar(2) * 5 / 14
        end

        t6 = 0
        loop for t5 = 1 to c6
          xf(t5) = t6
          t6 += vpar(6)                 /* average x increment (a guess)
        repeat

        beamfy = mf(1)
* reverse if stem down
        t3 = 0
        if stem = DOWN
          t3 = 300 * vpar(1) - vpar(8)
          t3 = 150 * vpar(2) - vpar(8)
          loop for t6 = 1 to c6
            mf(t6) = 300 * vpar(1) - mf(t6)
            mf(t6) = 150 * vpar(2) - mf(t6)
          repeat
        end
        zstaff = t3
* determine slope and pivot of beam
        t9  = 0
        x1  = 5000
        y1  = 5000
        t11 = 6
        t1  = 0
        t4  = 0          /* changes in absolute height
        t2  = 0
        t5  = mf(1)

   identify:  t9 = 6 - smallest note type under beam
             (x1,y1) = position of note closest to beam
             (x2,y2) = position of note next closest to beam
              t1 = y coordinate of note furthest from beam

        loop for t6 = 1 to c6
*  also compute sum of absolute changes in vertical height
          t8 = t5 - mf(t6)
          testfor t8 < 0
            if t2 = 0
              t2 = -1
            end
            if t2 = 1
              t2 = 2
            end
            t8 = 0 - t8
          else (>)
            if t2 = 0
              t2 = 1
            end
            if t2 = -1
              t2 = 2
            end
          end
          t5 = mf(t6)
          t4 += t8
*
          t8 = 0                 /* number of additional beams on this note
          loop while beamcode(t6) > 9
            ++t8
            beamcode(t6) /= 10
          repeat
          if t8 > t9
            t9 = t8              /* max number of additional beams
          end
          if t8 < t11
            t11 = t8             /* min number of additional beams
          end

          t8 = mf(t6)
          if t8 > t1
            t1 = t8              /* lowest y co-ord of notes in beam set
          end
          if t8 < y1
            y2 = y1
            x2 = x1
            y1 = t8              /* nearest y co-ord
            x1 = xf(t6)
          else
            if t8 < y2
              y2 = t8
              x2 = xf(t6)
            end
          end
        repeat

     Check point one: (x1,y1); (x2,y2); t1  set

        vrange = t1 - y1

     Formula for initial stem length

         note     t9      y1-t8
       ───────  ──────   ───────
         8th:      0      beamh
        16th:      1      beamh + (1 * notesize / 4)
        32th:      2      beamh + (4 * notesize / 4)
        64th:      3      beamh + (7 * notesize / 4)
       128th:      4      beamh + (10 * notesize / 4)
       256th:      5      beamh + (13 * notesize / 4)

        beamtype = t9
        if t9 = 0
          t8 = y1 - beamh
        else
          t8 = t9 * 3 - 2
          t8 = 0 - notesize * t8 / 4 - beamh + y1
        end
        t1 = x1
*   deal with case of severe up-down pattern
        if t2 = 2
          t4 /= c6
          if t4 > bvpar(18)
            slope = 0
            goto GSB1
          end
        end
*
        slope = y1 - y2 * 2 * BHPAR1
        t7 = x1 - x2
        slope /= t7

   Comment: slope is (2*BHPAR1) times slope between two notes
                 nearest the beam

        t7 = mf(c6) - mf(1) * 2 * BHPAR1
        t6 = xf(c6)
        if t6 < vpar(5)
          t6 = vpar(5)
        end
        t7 /= t6

   Comment: t7 is (2*BHPAR1) times slope between outside notes

   Formula:  slope = (slope + t7) / 6   provided

      |slope| must be equal to or less than |t7|

        t6 = abs(slope) - abs(t7)
        if t6 > 0
          if slope > 0
            slope -= t6
          else
            slope += t6
          end
        end
*
        slope = slope + t7 / 6
GSB1:   t7 = abs(slope)
        if t7 > BHPAR1 / 2
          t7 = BHPAR1 / 2
        end
*   Soften slant for thirty-seconds and smaller
        if t9 > 2 and t7 > 5
          t7 = 0 - t9 / 2 + t7
        end
        if t7 < 0
          t7 = 0
        end

   set reduce slant if end note are closer than vpar(6)

        t4 = xf(c6)
        if t4 <= vpar(6)  and  t7 > bvpar(35)
          t7 = bvpar(35)
        end

   shorten shortest stem, if gradual slope and large vertical range
                               and relatively high note

        if vrange > vpar(3)
          t4 = t9 * beamt + t8 - zstaff
          t4 = 0 - t4
          if t4 > vpar(3)
            if t7 < 6
              if x1 > 0 and x1 < xf(c6)
                t8 += bvpar(17)
              end
              if c6 = 2
                t8 += bvpar(17)
              end
            end
          end
        end
*
        if slope < 0
          slope = 0 - t7
        else
          slope = t7
        end

   slope   = BHPAR1 * slope of beam
   t8      = y coordinate of pivot point (on highest note) of first beam
   t7      = absolute value of @m
   t3      = y coordinate of top of staff line
   (x1,y1) = coordinate of note closest to beam (highest note)
   (x2,y2) = coordinate of second closest note to beam (2nd highest note)
   t9      = 6 - smallest note type number (number of beams - 1
   t11     = 6 - largest note type number

        ypiv = t8
        ++t9

     Check point two:  t9 = number of beams, current slope = slope

    Adjust slope and t8 so that beams will fall properly on staff lines

     Case I:   slope = 0

GCSI:   if slope = 0
          t2 = t9 - 1 * notesize + t8
          if t2 >= t3

     Adjust flat beam height

            t5 = t2 - t3 / notesize
            if t9 = 1  and   rem <= bvpar(20)
              rem += bvpar(20)
            end
            if t9 = 2
              if rem <= bvpar(20)
                rem += bvpar(34)
              else
                rem = rem - notesize + bvpar(20)
              end
            end
            if t9 = 3
              rem += bvpar(34)
            end
            if t9 = 4
              if t5 = 3
                beamt = bvpar(33)
              end
              if t5 < 3
                t5 = rem
                t5 -= vpar(1) / 2
                rem = t5
              end
            end
            t8 -= rem
*     (*) extremely low notes
            if t9 = 1
              t2 = vpar(4) + zstaff
            else
              t2 = 4 - t9 * vpar(2) + zstaff
            end
            if t8 > t2
              t8 = t2
              if t9 > 3  and  c5 = 0
                beamt = bvpar(33)
              end
            end
          end
        else

     Case II:   slope <> 0

          loopcnt = 0
GCSII:
          ++loopcnt
          t6 = 0 - x1 * slope / BHPAR1 + t8
          t5 = xf(c6) * slope / BHPAR1 + t6
          t2 = t5 + t6 / 2
          if t9 > 1
            if t11 > 0
              t2 += beamt
              if t9 = 2
                t2 += 2
              end
            end
            t10 = bvpar(22)
          else
            t10 = bvpar(23)
          end
   t6  = starting point of top beam
   t5  = stopping point of top beam
   t2  = average height of beam (second beam if always 2 or more)
   t10 = fudge factor
          t4 = t3
          t3 -= notesize
          if t9 > 2
            t3 -= notesize
          end
          if t2 > t3

     Adjust slanted beam height

            if t9 > 2
              if t2 > t4
                beamt = bvpar(33)
              else
                t2 -= 2
              end
            end
            t4 = abs(t5 - t6)
            t5 = t2 - t3 / notesize
            t5 = rem
   t4 = rise/fall of beam
   t5 = amount by which the average beam height lies below a line
            if t4 < bvpar(24)
              if t5 >= t10
                t5 -= notesize
                if t9 = 1
                  ++t5
                end
              else
                if t9 = 1
                  --t5
                end
              end
              t8 -= t5
              goto GCV
            end
            if t4 < beamt
              if loopcnt > 4
                goto GCV
              end
              if t7 > 1
                goto GCSJJ
              end
              ++t7
              if slope < 0
                slope = 0 - t7
              else
                slope = t7
              end
              goto GCSII
            end
            if t4 < bvpar(25)
              t5 += vpar(1)
              c16 = t5 * 2 / vpar(2)
              if rem <> 0
                ++t5
              end
              t5 += vpar(1)

              if t5 > t10
                t5 -= notesize
              end
              t8 -= t5
              goto GCV
            end
            if t4 > bvpar(26)
              if t5 > t10
                t5 -= notesize
              end
              t8 -= t5
              goto GCV
            end
            if t7 = 2
              t5 += vpar(1)
              c16 = t5 * 2 / vpar(2)
              if rem <> 0
                ++t5
              end
              t5 += vpar(1)

              if t5 > t10
                t5 -= notesize
              end
              t8 -= t5
              goto GCV
            end
            if loopcnt > 4
              goto GCV
            end
GCSJJ:      --t7
            if slope < 0
              slope = 0 - t7
            else
              slope = t7
            end
            goto GCSII
          else
            if t9 < 4
              t8 = notesize / 3 + t8
            end
          end
*   Check for extra low notes
GCV:      t4 = 0 - x1 * slope / BHPAR1 + t8
          t6 = xf(c6) - x1 * slope / BHPAR1 + t8
          t5 = 0
          if t9 = 1
            t2 = vpar(4) + zstaff - 2
          else
            t2 = 4 - t9 * notesize + zstaff - 2
          end
          if slope > 0
            if t4 > t2
              t5 = 1
              t4 = t2 + 1
            end
          else
            if t6 > t2
              t5 = 1
              t6 = t2 + 1
            end
          end
          t2 = t2 + bvpar(20) + 2
          if slope > 0
            if t6 > t2
              t5 = 1
              t6 = t2
            end
          else
            if t4 > t2
              t5 = 1
              t4 = t2
            end
          end
          if t5 = 1
*    Correction necessary
            t7 = xf(c6)
            slope = t6 - t4 * BHPAR1 / t7
            t8 = x1 * slope / BHPAR1 + t4
            t7 = abs(slope)
          end
          t8 -= vpar(1) / 2
        end
*
        t12 = slope * t1
        t12 = t8 * BHPAR1 - t12

     Check point three:  beam slope = slope;
                         y intercept (times BHPAR1) = t12

      Post adjustment:  sometimes the stems of sixteenths are too
        short.  This will be the case when (y2-t8) - ((t9-1)*beamt) < xxx
        where xxx is some number.  In this case, we should raise the
        beam by some small amount, yyy.

        t6 = 0 - (t9 - 1) * beamt + y2 - t8
        if t6 < bvpar(29)
          t12 -= bvpar(30) * BHPAR1
        end

      In the case where c6 = 4, compare sum of the first two notes
      verses the last two notes.  If the direction is different from
      the slope, then the slope should be zero.

        if c6 = 4
          t2 = mf(1) + mf(2)
          t3 = mf(3) + mf(4)
          if t2 > t3
            if slope > 0
              goto GSB2
            end
          end
          t2 = t2 - t3 * slope
          if t2 > 0
            goto GSB2
          end
          goto GSB3
GSB2:     slope = 0
          t3 = zstaff
          t8 = ypiv
          goto GCSI
        end
GSB3:

   slope = BHPAR1 * slope of beam
   t12   = y-intercept of beam (times BHPAR1)


        t8 = vpar(6) / 7
        if beamtype > 0
          t8 = vpar(5) / 4
        end
        t12 /= BHPAR1

        if stem = DOWN
          t12 = 300 * vpar(1) - t12 + bthick - t8
          t12 = 150 * vpar(2) - t12 + bthick - t8
          slope = 0 - slope
        else
          t12 += t8
        end
        passback slope, t12
      return

 ┌──────────────────────────────────────────────────────────────┐
 │P 33. display_array                                           │
 │                                                              │
 │                                                              │
 │    Purpose:  Print out the current state of the ts array     │
 │                Used for debugging                            │
 └──────────────────────────────────────────────────────────────┘

      procedure display_array
        int g

        g = measnum - 1
        if bit(2,pmode) = 1 and g >= debug_point

     Condition changed 01/01/06

        if (bit(2,pmode) = 1 or debug_flag = 1) and g >= debug_point
          putc   Set Array at procedure call:  measure ~g
          putc Look?
          getc jtype
          if jtype = "y"
            perform display_ts
          end
        end
      return

 ┌──────────────────────────────────────────────────────────────┐
 │P 34. rest_occupy_space (t1,t2)                               │
 │                                                              │
 │                                                              │
 │    Purpose:  For a given location on the staff line and      │
 │                a given type of rest, set the gr(.,.) and     │
 │                gl(.,.) arrays to reflect the placement       │
 │                of the rest in this spot                      │
 │                                                              │
 │    Inputs:   ntype  = type of rest                           │
 │              t1     = position on staff (0 = top line)       │
 │                         (i.e.,STAFFLOC)                      │
 │              t2     = staff number                           │
 │                                                              │
 └──────────────────────────────────────────────────────────────┘

      procedure rest_occupy_space (t1,t2)
        int t1,t2,t3,t4,t5,t6,t7,t8

        getvalue t1,t2
        t1 = 0 - t1 / vpar(1) + 23
        c16 = t1 + vpar20 * 2 + 1 / vpar(2) - 20
        t1 = 23 - c16

        t5 = ntype << 1 - 1

        t3 = int("1008060402020402030303"{t5,2})
        t4 = int("0505050505030301000101"{t5,2})

        if ntype > WHOLE
          t6 = hpar(87) * 4 / 3
        else
          if ntype > QUARTER
            t6 = hpar(87)
          else
            if ntype > EIGHTH
              t6 = hpar(88)
            else
              t6 = EIGHTH - ntype * hpar(54) + hpar(88)
            end
          end
        end
        t6 += hpar(85)

        t7 = t1 - t4
        if t7 < 1
          t7 = 1
        end
        t8 = t1 + t3
        if t8 > 45
          t8 = 45
        end
        loop for t5 = t7 to t8
          gr(t2,t5) = t6
          gl(t2,t5) = 0
        repeat
      return

 ┌───────────────────────────────────────────────────────────────────────┐
 │P 35. place_accidental (t1,t2,t3,t4)                                   │
 │                                                                       │
 │                                                                       │
 │    Purpose:  Determine the absolute x-location of an                  │
 │                accidental, given gl(.,.) and the imputs:              │
 │                                                                       │
 │    Inputs:   t1     = staff number                                    │
 │              t2     = position on staff (23 = top line)               │
 │              t3     = accidental code                                 │
 │              t4     = note size (full size vs. cue size)              │
 │                                                                       │
 │    Output:   t4     = absolute x location                             │
 │              t3     = SCORE P5 data:                                  │
 │                         t3 & 0x00ff = P5 fractional position data     │
 │                         t3 & 0x0f00 = P5 one's data                   │
 │                         t3 & 0xff0000 = left shift (dots) for natural │
 │                                                                       │
 └───────────────────────────────────────────────────────────────────────┘

      procedure place_accidental (t1,t2,t3,t4)
        int t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,savet3,savet4,t14

        getvalue t1, t2, t3, t4
        t14 = t4

        if t2 > 42 or t2 < 3 or t3 = 10    /* use old system
          t5 = t2 - int("221002200100001"{t3})  /* lower limit
          t6 = t2 + int("333003300200003"{t3})  /* upper limit
          t8 = 200
          loop for t7 = t5 to t6
            if t7 > 0 and t7 <= 45
              if gl(t1,t7) < t8
                t8 = gl(t1,t7)
              end
            end
          repeat
          t9 = hpar(t3)
          if t14 = CUESIZE
            t9 = t9 * 8 / 10    /* cue or grace size
          end
          t4 = t8 - t9          /* absolute x position
          loop for t7 = t5 to t6
            if t7 > 0 and t7 <= 45
              gl(t1,t7) = t4   /* new global left boundary
            end
          repeat
          passback t4

          t10 = 0
          if t3 = 6 or t3 = 7
            t10 = 0 - t4       /* relative leftward position of CODE-9 natural

       In SCORE, the position of an ax is the right, not left boundary

            if t14 = CUESIZE
              t10 -= (hpar(1) * 8 / 10)
            else
              t10 -= hpar(1)
            end

            t3 -= 4            /* remove natural from code
          end
          t8 = 0 - t8
          if t8 < 0
            t8 = 0
          end

    New 10/25/07

       In SCORE, the shifting of an accidental to the left is coded as .25 units
         per accidental width.  Dmuse units are in dots, so there needs to be a
         conversion.  The formula would be something like this:

         14 dots = 25 units
         t8 (in units) = t8 (in dots) * 25 / vpar(2)

        t8 = t8 * 25 / vpar(2)


          t3 = int("321......5....4"{t3})   /* converting form MUSEDATA code to SCORE code
          t3 = t3 << 8
          t3 += (t10 << 16)
          t3 += t8
          passback t3

          return
        end

  hpar(1)  =  shift following accidental natural
  hpar(2)  =  shift following accidental sharp
  hpar(3)  =  shift following accidental flat
  hpar(6)  =  shift following accidental natural-sharp
  hpar(7)  =  shift following accidental natural-flat
  hpar(10) =  shift following accidental double sharp
  hpar(15) =  shift following accidental double flat


     (1) determine absolute x location

        if chr(t3) in [3,7,15]
          t5 = hpar(3) * 7 / 10
          t6 = gl(t1,t2+3) + t5
          loop for t7 = t2 - 1 to t2 + 2
            if gl(t1,t7) < t6
              t6 = gl(t1,t7)
            end
          repeat
          if t3 = 7 and gl(t1,t2-2) + hpar(3) < t6
            t6 = gl(t1,t2-2) + hpar(3)
          end
        else
          if chr(t3) in [2,6]
            t5 = hpar(2) * 2 / 10
            t6 = gl(t1,t2+3) + t5
            loop for t7 = t2 - 1 to t2 + 2
              if gl(t1,t7) < t6
                t6 = gl(t1,t7)
              end
            repeat
            if t6 > gl(t1,t2-2) + t5
              t6 = gl(t1,t2-2) + t5
            end
          else
            t5 = hpar(3) * 6 / 10
            t6 = gl(t1,t2+3) + t5
            loop for t7 = t2 - 2 to t2 + 2
              if gl(t1,t7) < t6
                t6 = gl(t1,t7)
              end
            repeat
          end
        end
        t5 = hpar(t3)
        if t14 = CUESIZE
          t5 = t5 * 8 / 10    /* cue or grace size
        end
        t4 = t6 - t5                        /* absolute x position
        passback t4

        savet3 = t3

        t10 = 0
        if t3 = 6 or t3 = 7
          t10 = 0 - t4       /* relative leftward position of CODE-9 natural

       In SCORE, the position of an ax is the right, not left boundary

          if t14 = CUESIZE
            t10 -= (hpar(1) * 8 / 10)
          else
            t10 -= hpar(1)
          end

          t3 -= 4            /* remove natural from code
        end
        t6 = 0 - t6
        if t6 < 0
          t6 = 0
        end

    New 10/25/07

       In SCORE, the shifting of an accidental to the left is coded as .25 units
         per accidental width.  Dmuse units are in dots, so there needs to be a
         conversion.  The formula would be something like this:

         14 dots = 25 units
         t6 (in units) = t6 (in dots) * 25 / vpar(2)

        t6 = t6 * 25 / vpar(2)


        t3 = int("321......5....4"{t3})   /* converting from MUSEDATA code to SCORE code
        t3 = t3 << 8
        t3 += (t10 << 16)
        t3 += t6
        passback t3

        t3 = savet3

     (2) determine new values for gl(.,.)

        if chr(t3) in [1,6,7]
          loop for t7 = t2 - 1 to t2 + 3
            gl(t1,t7) = t4                  /* new global left boundary
          repeat
          gl(t1,t2-2) = hpar(1) / 2 + t4
        else
          if chr(t3) in [3,15]
            loop for t7 = t2 - 1 to t2 + 3
              gl(t1,t7) = t4                /* new global left boundary
            repeat
          else
            t5 = hpar(2) / 10
            gl(t1,t2+3) = t4 + t5
            loop for t7 = t2 - 1 to t2 + 2
              gl(t1,t7) = t4                /* new global left boundary
            repeat
            gl(t1,t2-2) = t4 + t5
          end
        end
      return

 ┌──────────────────────────────────────────────────────────────┐
 │P 36. typeset_tuple (t1,t2,t3)                                │
 │                                                              │
 │    Purpose:  Typeset tuple companion to repeater             │
 │                                                              │
 │    Inputs:   t1     = tuple number                           │
 │              t2     = centered x-location to place tuple     │
 │              t3     = y-location to place tuple              │
 │                                                              │
 └──────────────────────────────────────────────────────────────┘

      procedure typeset_tuple (t1,t2,t3)
        int t1,t2,t3
        int savex,savey,savez

        getvalue t1,t2,t3

        savex = x
        savey = y
        savez = z
        x = t2
        y = t3
        kscrdat = ""
        if t1 > 9
          x -= hpar(104)
          z = t1 / 10 + 221
          t1 = rem
          perform subj
          x += hpar(105)
          z = t1 + 221
          perform subj
        else
          z = t1 + 221
          perform subj
        end
        x = savex
        y = savey
        z = savez

      return

#if AUTOSCR

 ┌────────────────────────────────────────────────────────────────┐
 │P 37. build_note_kscrdat                                        │
 │                                                                │
 │    Purpose:  build the kscrdat string for note heads           │
 │                                                                │
 │    Inputs:  c3       = pointer into set array for this note    │
 │             y        = vertical position of notehead on staff  │
 │             ntype    = type of note (e.g. sixteenth)           │
 │             note_dur = duration of note (in divisions)         │
 │             divspq   = divspq                                  │
 │             nodtype  = NOTE, GR_NOTE, or CUE_NOTE              │
 │                                                                │
 │    Output:  kscrdat string                                     │
 │                                                                │
 │    Operation:  Compute full values for:    P2 P4 P6 P7 P10 P12 │
 │                Compute partial values for: P5 P9               │
 │                Not computed here:          P3 P8               │
 │                                                                │
 └────────────────────────────────────────────────────────────────┘

      procedure build_note_kscrdat
        int t1,t2,t3,t4
        int staff,track,pri_staff,p21,p22,p4,p5,p61,p62,p71,p72,p8,p9,p10,p12

        pri_staff = 0
        track = ts(c3,TRACK_NUM)
        staff = ts(c3,STAFF_NUM) + 1
        if track > 0
          pri_staff = trackstave(opbarnum,track,3)
        end

     Compute values for P2 P4 P5 P6 P7 P8 P9 P10 P12

        p12 = 0
        if pri_staff > 0
          if pri_staff = 1 and staff = 2
            p12 = 2
          end
          if pri_staff = 2 and staff = 1
            p12 = 1
          end
          p21 = pri_staff
        else
          p21 = staff
        end
        p22 = track

        p4 = (0 - y) / vpar(1) + 11
        kscrdat = " | P2=" // chs(p21) // "." // chs(p22) // " P4=" // chs(p4)

        t1 = ts(c3,AX_DISP)
        if t1 = 0
          kscrdat = kscrdat // " P5=0"
        else
          t2 = t1 & 0xff
          t3 = t1 & 0xff00 >> 8
          kscrdat = kscrdat // " P5=" // chs(t3) // "."
          if t2 < 10
            kscrdat = kscrdat // "0"
          end
          kscrdat = kscrdat // chs(t2)
          t1 >>= 16
          if t1 <> 0
            kscrdat = kscrdat // "+Nat@" // chs(t1) // "<-"
          end
        end

        if ntype < 8
          p61 = 0
        else
          p61 = ntype - 7
        end
        p62 = ts(c3,BASE_40)
        p62 = ts(c3,BASE_40) + pitch_mod                   /* New 11/27/09
        kscrdat = kscrdat // " P6=" // chs(p61) // "."
        if p62 < 10
          kscrdat = kscrdat // "0"
        end
        if p62 < 100
          kscrdat = kscrdat // "0"
        end
        kscrdat = kscrdat // chs(p62)

        if nodtype = NOTE or nodtype = CUE_NOTE
          p71 = 10000 * note_dur / divspq
          p71 = p71 / 10000
          p72 = rem
          kscrdat = kscrdat // " P7=" // chs(p71) // "."
          if p72 < 10
            kscrdat = kscrdat // "0"
          end
          if p72 < 100
            kscrdat = kscrdat // "0"
          end
          if p72 < 1000
            kscrdat = kscrdat // "0"
          end
          kscrdat = kscrdat // chs(p72)
        else                                 /* GR_NOTE
          kscrdat = kscrdat // " P7=-1.0000"                /* needs further clarification
          kscrdat = kscrdat // " P7=65.00"
        end

        t1 = ts(c3,AUG_DOTS)
        if t1 > 0
          t2 = t1 >> 24
          if t2 = 0
            t3 = t1 & 0xff
            t2 = t1 & 0xff00 >> 8
            kscrdat = kscrdat // " P9=" // chs(t2) // "."
            if t3 < 10
              kscrdat = kscrdat // "0"
            end
            kscrdat = kscrdat // chs(t3)
          else
            kscrdat = kscrdat // " " // chs(t2) // "Dots@x+"
            t1 &= 0xffffff
            t1 /= INT10000
            if rem > (INT10000 >> 1)
              t2 = INT10000 - rem
              ++t1
              kscrdat = kscrdat // chs(t1) // "y-" // chs(t2)
            else
              kscrdat = kscrdat // chs(t1) // "y" // chs(rem)
            end
          end
        end

        t1 = ts(c3,NOTE_DISP)                /* can be 100,0,-100 or large
        t2 = ts(c3,LOCAL_XOFF)
        if t2 > 0                            /* set t2 to 100,0,or -100
          t2 = 100
        end
        if t2 < 0
          t2 = -100
        end
        if t2 + t1 <> 0
          if t2 + t1 = 100
            kscrdat = kscrdat // " P10=10"
          else
            if t2 + t1 = -100
              kscrdat = kscrdat // " P10=20"
            else
              if t2 + t1 = 200
                kscrdat = kscrdat // " P10=6"
              else
                if t2 + t1 = -200
                  kscrdat = kscrdat // " P10=-6"
                else
                  t1 = t1 / INT10000
                  if rem > (INT10000 >> 1)
                    t3 = INT10000 - rem
                    ++t1
                  else
                    t3 = rem
                  end
                  t3 = t3 * 300 / t1          /* 100 times too big
                  t2 *= 3                     /* 100 times too big
                  t3 += t2
                  if t3 > 0
                    t3 = t3 / 100
                    t1 = rem
                    kscrdat = kscrdat // " P10=" // chs(t3) // "."
                  else
                    t3 = 0 - t3
                    t3 = t3 / 100
                    t1 = rem
                    kscrdat = kscrdat // " P10=-" // chs(t3) // "."
                  end
                  if t1 < 10
                    kscrdat = kscrdat // "0"
                  end
                  kscrdat = kscrdat // chs(t1)
                end
              end
            end
          end
        end

        kscrdat = kscrdat // " P12=" // chs(p12)
      return

#endif

 ┌────────────────────────────────────────────────────────────────┐
 │P 38. setarpeggio  (New 01/13/06)                               │
 │                                                                │
 │    Purpose:  write object arpeggio                             │
 │                                                                │
 │    Inputs:  c1           = pointer into set array for arpeggio │
 │             obx          = horizontal position of arpeggio     │
 │             arpeg_top    = top of arpeggio                     │
 │             arpeg_bottom = bottom of arpeggio                  │
 │             arpeg_flag   = extra length to span grand staff    │
 │             ntype        = ARPEGGIO                            │
 │             passnum      = pass number for this arpeggio       │
 │             inctype      = increment type for next node        │
 │                              with a new spn (used in putobj)   │
 │                                                                │
 └────────────────────────────────────────────────────────────────┘

      procedure setarpeggio
        int t1,t2,t3,t4,t5,t6,t7,t8,t9

        t3 = ts(c1,STAFF_NUM) * 1000
        oby = arpeg_top * 2 - 1 * vpar(2) / 2
        sobcnt = 0

        x = obx
        y = oby

        t1 = arpeg_bottom * 2 - 1 * vpar(2) / 2
        if arpeg_flag > 0
          t1 += arpeg_flag
        end

        z = 120                                 /* music font for arpeggio
        perform subj

        t2 = t1 - vpar(4)
        loop while y <= t2
          perform subj
          y += vpar(4)
        repeat
        y -= vpar(2)
        if y <= t2
          perform subj
        end

        jtype = "G"
        jcode = EIGHTH
        out = "0"

     Duration attribute of arpeggio

        ++sobcnt
        sobl(sobcnt) = "A D 1 8"

        pcode = sobcnt
        oby += t3
        putobjpar = 0

        t4 = ts(c1,TSR_POINT)
        pcontrol = ors(tsr(t4){1})                      /* 05/02/03
        px = ors(tsr(t4){3}) << 8
        py = ors(tsr(t4){4}) << 16
        t1 = ors(tsr(t4){2}) << 24
        putobjpar = t1 + px + py + pcontrol             /* Note: order of data has been changed

        perform putobj
        oby -= t3
      return

 ┌────────────────────────────────────────────────────────────────┐
 │P 39. survay_file                                               │
 │                                                                │
 │    Purpose: Survay the entire file and make a map of the       │
 │    number of tracks in each measure and of their staff         │
 │    position; also determine divspm and divspq for each         │
 │    measure; also determine if and where there are any time     │
 │    gaps.                                                       │
 │                                                                │
 │                                                                │
 └────────────────────────────────────────────────────────────────┘

      procedure survay_file
        str line2.200
        int i,j

        loop for i = 1 to MAX_MEAS
          loop for j = 1 to 9
            trackstave(i,j,1) = 0
            trackstave(i,j,2) = 0
            trackstave(i,j,3) = 0
          repeat
        repeat
        loop for i = 1 to 15000
          timegaps(i,1) = 0
          timegaps(i,2) = 0
          timegaps(i,3) = 0
        repeat

        scnt = 11         /* the first record better be a $ record or else!
GET_DOLLAR:
        tget [X,scnt] line
        ++scnt
        if line{1} = "P" or line{1} = "@"
          goto GET_DOLLAR
        end

        line = line // pad(100)
        if line{1} <> "$"
          putc Program error, or file error: expecting initial $ record.
          putc
          putc This is most likely a file error.  The most common error
          putc is a misrepresentation of the group membership structure
          putc in lines 11ff. of the data file.
          putc
          stop
        end
        if line con "C2:"
          staves = 2
        else
          staves = 1
        end
        if line con "Q:"
          divspq = int(line{mpt+2..})
        else
          putc Program error, or file error: divspq not specified.
          putc Record ~(scnt+12)  ~line
          stop
        end
MMPR:
        ++barnum
        measuremap(barnum,1)  = 0
        measuremap(barnum,2)  = 0
        measuremap(barnum,3)  = 0
        measuremap(barnum,4)  = 0
        measuremap(barnum,5)  = divspq
        durflag = 0

        divpoint = 0
        loop for i = 1 to 9
          trackdivpnt(i) = 0
        repeat
        track = 1
        staff = 1
        if track_flag = 1
          loop for i = 1 to 9
            trackstave(barnum,i,3) = track_assign(i)
          repeat
        end
MPR:
        tget [X,scnt] line
        ++scnt
        line = line // pad(80)
        if line{8} <> " "
          d = int(line{6,3})         /* possible duration
        end
        g = int(line{9,4})           /* possible measure number

        if line{1} = "$"
          if line con "Q:"
            divspq = int(line{mpt+2..})
            if durflag = 0
              measuremap(barnum,5)  = divspq   /* divspq can be set before durations in a meas.
            end
          end
          sugg_flg = 0
          goto MPR
        end

        if line{1} = "P"
          goto MPR
        end

        if line{1} = "@"
          if line con "track assignment:"
            line2 = line{mpt+17..}
            line2 = line2 // "   *"
            loop while line2 con "("
              a1 = int(line2{mpt+1..})
              a2 = int(line2{sub+1..})
              line2 = line2{sub+1..}
              trackstave(barnum,a1,3) = a2     /* re-assign track a1 to staff a2
              track_assign(a1) = a2            /*   and make change in assignment array
            repeat
          end
          if line con "instrument number:"
            line2 = line{mpt+18..}
            line2 = line2 // "   *"
            instrument_number = int(line2)
          end
          if line con "transposition:"
            line2 = line{mpt+14..}
            line2 = line2 // "   *"
            transposition = int(line2)
          end
          goto MPR
        end

        if "ABCDEFGri" con line{1}         /* note or rest
          durflag = 1
          if line{8} = " "
            putc File error: expecting a duration for this record
            putc Record ~(scnt+12)  ~line
            stop
          end
          if "123456789" con line{15}
            track = mpt
          else
            track = 1
          end
          if "123456789" con line{24}
            staff = mpt
          else
            staff = 1
          end
          if trackdivpnt(track) <> divpoint         /* time gap exists here
            if trackdivpnt(track) > divpoint
              putc File format error: track events out of time order
              putc Record ~(scnt+12)  ~line
              stop
            end

            ++tgpnt
            if measuremap(barnum,2) = 0
              measuremap(barnum,3) = tgpnt
            end
            ++measuremap(barnum,2)

            timegaps(tgpnt,1) = track
            timegaps(tgpnt,2) = trackdivpnt(track)
            timegaps(tgpnt,3) = divpoint - trackdivpnt(track)
            trackdivpnt(track) = divpoint
          end
          trackdivpnt(track) += d
          divpoint += d
          trackstave(barnum,track,staff) += d
          goto MPR
        end

        if line{1} = " "                  /* chord?
          if "123456789" con line{15}
            if track = mpt                /* true chord
              goto MPR
            end
            track = mpt
          else
            goto MPR                      /* true chord
          end
          if "123456789" con line{24}
            staff = mpt
          end
          if trackdivpnt(track) <> divpoint - d     /* time gap exists here

            if trackdivpnt(track) > divpoint - d
              putc File format error: track events out of time order
              putc Record ~(scnt+12)  ~line
              stop
            end

            ++tgpnt
            timegaps(tgpnt,1) = track
            timegaps(tgpnt,2) = trackdivpnt(track)
            timegaps(tgpnt,3) = divpoint - d - trackdivpnt(track)
            trackdivpnt(track) = divpoint - d
          end
          trackdivpnt(track) += d
          trackstave(barnum,track,staff) += d
          goto MPR
        end

        if line{1} = "c"
          putc Warning: cue notes may not be handled properly in this program
          goto MPR
        end
        if line{1} = "b"           /* backup command
          divpoint -= d
          goto MPR
        end
        if line{1} = "m"
          loop for i = 1 to 9
            if trackdivpnt(i) > divpoint
              putc File error: time pointer not fully advanced at end of measure
              putc Record ~(scnt+12)  ~line
              stop
            end
            if trackdivpnt(i) > 0 and trackdivpnt(i) < divpoint   /* time gap exists here
              ++tgpnt
              if measuremap(barnum,2) = 0
                measuremap(barnum,3) = tgpnt
              end
              ++measuremap(barnum,2)

              timegaps(tgpnt,1) = i
              timegaps(tgpnt,2) = trackdivpnt(i)
              timegaps(tgpnt,3) = divpoint - trackdivpnt(i)
              trackdivpnt(i) = divpoint
            end
          repeat
          measuremap(barnum,4) = divpoint
          loop for i = 1 to 9
            if trackstave(barnum,i,1) > 0 or trackstave(barnum,i,2) > 0
              ++measuremap(barnum,1)
            end
          repeat
          goto MMPR
        end

        if line{1} <> "/"
          goto MPR
        end
        --barnum

    Check for time gaps

        loop for i = 1 to barnum
          if measuremap(i,2) > 0
            i = MAX_MEAS * 10
          end
        repeat
        if i > MAX_MEAS * 9
          putc
          putc     A survay of this stage2 file detected some time gaps, which may
          putc     be perfectly legal in terms of the MUSEDATA stage2 format, but
          putc     which introduce added complexity in music searching and in score
          putc     conversion.  These applications require that the time gaps be
          putc     filled before proceeding any further with the i-file compilation
          putc     process.  The report below shows the bar numbers where the time
          putc     gaps occur.  Be sure to use the correct track number when you
          putc     add irests (the most common solution to filling time gaps).
          putc     You will probably also need to make use of the backup command
          putc     (back   # record) to keep the division pointer in the right place.
          putc
          putc                          ╔═══════════════╗
          putc                          ║  R E P O R T  ║
          putc                          ╚═══════════════╝
          putc
          putc     This movement has ~barnum  bars.  Note:  Some of these may
          putc     be double bars or heavy bars within normal bars, and may not
          putc     have bar numbers.  In this situation, the bar number column
          putc     below will not correspond to actual meausure numbers.
          putc
          putc                 Active    Time
          putc   Bar number │  Tracks    Gaps  divspm   divspq
          putc ─────────────┼─────────────────────────────────────
          loop for i = 1 to barnum
            putc .w6    ~i     │~measuremap(i,1)   ~measuremap(i,2)   ~measuremap(i,4)   ~measuremap(i,5)
          repeat
          putc             ─┼─
          putc
          putc                         Detail on Time Gaps
          putc                       ═══════════════════════
          putc
          putc                         Gap starts   Lasts #
          putc   Bar number │  Track    at div #   divisions
          putc ─────────────┼─────────────────────────────────────
          loop for i = 1 to barnum
            k = measuremap(i,3) - 1
            loop for j = 1 to measuremap(i,2)
              ++k
              putc .w6    ~i     │~timegaps(k,1)   ~timegaps(k,2)       ~timegaps(k,3)
            repeat
          repeat
          putc ─────────────┼─────────────────────────────────────
          putc
          putc  ┌──────────────────┐
          putc  │  Program Halted  │
          putc  └──────────────────┘
          putc
          stop
        end
        if staves = 2 and track_flag = 0
          putc
          putc     This stage2 file displays music on the grand staff.  This
          putc     means that it is possible for tracks to jump between staves.
          putc     SCORE requires that every musical track be assigned to a
          putc     "primary" staff, on a measure-by-measure basis.  Most tracks
          putc     will live their entire lives on the top or the bottom stave,
          putc     but some will jump around.  In many of these cases, it is
          putc     still possible that the "primary" staff will remain the same
          putc     throughout the movement.  However, there are some cases
          putc     where the primary staff really does change.  Where this
          putc     happens is not always easy to determine.  There are many
          putc     factors to consider, such as voice range, what else is on
          putc     the staff, and the presence of ties.  Perhaps some day
          putc     autoscr will be able to make these decisions automatically,
          putc     but for the time being, we must ask you, the user, to help
          putc     us with this.
          putc
          putc     The report below shows the track activity for the first 6 tracks
          putc     on a bar-by-bar basis.  Only those tracks that appear on both
          putc     staves are in question.
          putc
          putc     Type "Enter"
          getc
          putc                             ╔═══════════════╗
          putc                             ║  R E P O R T  ║
          putc                             ╚═══════════════╝
          putc
          putc                        T R A C K    A C T I V I T Y
          putc                      ════════════════════════════════
          putc
          putc           Track-1    Track-2    Track-3    Track-4    Track-5    Track-6
          putc   Bar  │  S1   S2    S1   S2    S1   S2    S1   S2    S1   S2    S1   S2
          putc ───────┼────────────────────────────────────────────────────────────────────
          loop for i = 1 to barnum
            putc .w3  ~i    │ ~trackstave(i,1,1)   ~trackstave(i,1,2)  │ ...
            putc .w3 ~trackstave(i,2,1)   ~trackstave(i,2,2)  │ ...
            putc .w3 ~trackstave(i,3,1)   ~trackstave(i,3,2)  │ ...
            putc .w3 ~trackstave(i,4,1)   ~trackstave(i,4,2)  │ ...
            putc .w3 ~trackstave(i,5,1)   ~trackstave(i,5,2)  │ ...
            putc .w3 ~trackstave(i,6,1)   ~trackstave(i,6,2)  │
          repeat
          putc       ─┼────────────────────────────────────────────────────────────────────
          putc    Type "Enter"
          getc
          putc
          loop for i = 1 to 9
            h = 0
            k = 0
            loop for j = 1 to barnum
              if trackstave(j,i,1) > 0
                ++h
              end
              if trackstave(j,i,2) > 0
                ++k
              end
            repeat
            if h > 0 and k = 0
              putc Track ~i  will be assigned to stave 1
              loop for j = 1 to barnum
                trackstave(j,i,3) = 1
              repeat
            end
            if h = 0 and k > 0
              putc Track ~i  will be assigned to stave 2
              loop for j = 1 to barnum
                trackstave(j,i,3) = 2
              repeat
            end
            if h > 0 and k > 0
AQQQ:
              a3 = 1
              putc We need help with Track ~i
              putc Which staff should be primary staff at the start of the piece? (1 or 2)
              getc a1
              putc Track ~i  will start with staff ~a1  as primary
AQQ:
              a2 = 3 - a1
              putc
              putc At what bar number should track ~i  change its primary staff to staff ~a2 ?
              putc If no change, enter 1000. (or any number greater than total number of meas + 1)
              getc a4
              if a4 > barnum + 1
                a4 = barnum + 1
              end
              loop for j = a3 to a4 - 1
                trackstave(j,i,3) = a1
              repeat
              if a4 < barnum + 1
                a1 = a2
                a3 = a4
                goto AQQ
              end
              putc You have designated the following pattern for the primary staves of track ~i
              putc
              putc                     Track-~i
              putc             Bar  │  S1   S2
              putc           ───────┼─────────────
              loop for j = 1 to barnum
                if trackstave(j,i,3) = 1
                  putc           .w3  ~j    │ ~trackstave(j,i,1)   ~trackstave(j,i,2)
                else
                  putc           .w3  ~j    │ ~trackstave(j,i,1)   ~trackstave(j,i,2)
                end
              repeat
              putc                 ─┼─────────────
              putc
              putc Type Enter to accept.  A non-empty line will allow you to enter the data again.
              getc line
              line = trm(line)
              if line <> ""
                goto AQQQ
              end
            end
          repeat
        end

    Now check to see that every active track is assigned to a stave

        if staves = 2
          a3 = 0
          loop for a1 = 1 to barnum
            loop for a2 = 1 to 9
              if trackstave(a1,a2,1) + trackstave(a1,a2,2) > 0
                if trackstave(a1,a2,3) = 0
                  if a3 = 1
                    putc There are some measures where an active track is not assigned to a staff
                    putc The problem can be corrected by either:
                    putc    (1) adding @  SCORECON track assignment records at the
                    putc          measures in question, or
                    putc    (2) deleting all @  SCORECON track assignment records from
                    putc          the stage2 file
                    putc
                  end
                  a3 = 1
                  putc Track ~a2  in measure ~a1  is unassigned
                end
              end
            repeat
          repeat
          if a3 = 1
            putc
            putc               Program Halted
            putc
            stop
          end
        end

      To re-cap at this point, we now have gathered the following information
      to help us develop the parameters necessary to convert stage2 data to
      Score data:

      1. The total number of barlines in this movement is barnum

      2. number of staves for this stage2 file is staves

      3. For each measure, we know

         a) the number of active tracks in this measure is measuremap(.,1)

         b) there are no time gaps

         c) number of divisions in this measure is measuremap(.,4)

         d) governing divspq for this measure is measuremap(.,5)

         e) if staves = 2, the primary staff for each track is trackstave(.,.,3)

         f) a track is active if trackstave(.,.,1) + trackstave(.,.,2) > 0

         g) a track spans both staves if trackstave(.,.,1) > 0 and trackstave(.,.,2) > 0




      return

 ┌──────────────────────────────────────────────────────────────────────────────┐
 │P. XXX  check_for_lib (slib,nlib                                              │
 │                                                                              │
 │    Operation:  This procedure looks into the directory "slib" for the        │
 │                sub-directory "nlib".                                         │
 │                                                                              │
 │                if nlib does not appear in the sub-diretory,                  │
 │                  it is created as a sub-directory                            │
 │                else                                                          │
 │                  if nlib does appear in the sub-diretory, and                │
 │                    if it appears as a FILE,                                  │
 │                      an error message is printed and a stop command issued.  │
 │                    else                                                      │
 │                      the procedure returns with no action taken.             │
 │                    end                                                       │
 │                  end                                                         │
 │                end                                                           │
 │                                                                              │
 │    Inputs:     slib  = directory to look into                                │
 │                nlib  = sub-directory to look for, and possibly create        │
 │                                                                              │
 │    Possible Outcomes:                                                        │
 │                nlib is there, no action                                      │
 │                nlib is not there, and is created                             │
 │                nlib is there, but as a FILE.  Error and stop                 │
 └──────────────────────────────────────────────────────────────────────────────┘
      procedure check_for_lib (slib,nlib)
        str slib.200,nlib.80
        str fname.200
        getvalue slib,nlib

        nlib = trm(nlib)
        open [7,1] slib
        loop
          getf [7] line
          fname = line{33..}
          fname = trm(fname)
          if fname = nlib
            if line{1,5} = "<dir>"       /* this is a directory, not a file
              close [7]
              return
            else
              putc ~nlib  already exists as a FILE and cannot be created as a directory
              putc For purposes of this program, this is unexpected and must be considered
              putc an ERROR.
              putc              Program Halted
              putc
              stop
            end
          end
        repeat
eof7:
        close [7]
        line = slib // "/" // nlib
        createdir line
      return

      run



    
              Extra Lines for Debugging
    


        perform display_array         /* DEBUG



                if measnum - 1 >= 291
                  examine
                end