Musical Notation in SC using musicXML

I wrote a function that creates a musicXML file when the musical information is written as in example 1. With this, sclang can also easily request a server to play music. I attach this function with 5 examples. Example 3, 4 and 5 also contain how to request a server to play music. The examples below work on my end, but the function should be rewritten whenever other features are added. I would like to know what other users think about such work in SC.

1. Function: ~exportXML
https://www.dropbox.com/scl/fi/mxgk0ej96kqe0jt7i8au0/musicXMLgenerator.scd?rlkey=7sszsg4a776k1iu27k0pcq5ig&dl=0

2. Example 1: how to notate

(
/* A score should be written in bar notation as an array. */
~score1 = [

    /* The first element should be information about the composer, title and copyright. */
    // - Access: ~score1[0]
    (   title: 'untitled', composer: 'me', rights: '©'),

    /* The elements from the second to the last are musical notation events,
    and each event contains the musical information for each bar. */
    // - Access to all bars: ~score1[1..]
    // - Access to a specific bar: ~score1[barNumber]
    //                         ex.) ~score1[1]

    (   /* The notation information of a bar should be constructed as elements within an event. */
        // It contains the "bar number" with the key \bar
        // and all the parts of the bar with keys like \p1, \p2, etc:

        bar: 1,
        // - Access: ~score1[barNumber][\bar]
        //           ex.) ~score1[1][\bar]

        // ATTENTION:
        // The first bar should contain all the parts of the whole score even though
        // one or more particular parts do not appear in the first bar.

        /* Each part should be an event that contains its notation information in the bar. */
        // The value of the event key is an array containing the notation information of its part in the bar:
        p1:
        (
            lbl: \Soprano,
            // The \lbl key should contain its part name or staff label.
            // - Access: ~score1[barNumber][partNumber][\lbl]
            //           ex.) ~score1[1][\p1][\lbl]

            atr: // The \atr key should contain its attributes as an event:
            (
                key: // This defines the key signature.
                [ // ATTENTION: the order of the elements is important!
                    0 // The number of sharps or flats:
                    //    2:   two sharps, used for D major or B Minor
                    //    1:   one sharp, used for G major or E minor
                    //    0:   no sharps and no flats
                    //   -1:   one flat
                    //   -2:   two flats;
                    ,
                    \none // mode:
                    //         \none: atonal
                    //         \C: C-major
                    //         \a: A-minor
                ]
                ,

                time: // This defines the time signature.
                \x //       \x: senza-misura
                /*
                [ // ATTENTION: the order of the elements is important!
                4 // upper numeral (top number)
                ,
                4 // lower numeral (bottom number)
                ]
                */
                ,

                staves: // This defines the number of staves.
                1       // The number of staves
                ,

                clef: // This defines the clef and its position on each staff.
                [ // ATTENTION: the order of the elements is important!

                    // The clef definition for the first staff:
                    [ // ATTENTION: the order of the elements is important!
                        \c // The clef symbol:
                        //    \G: g-clef
                        //    \C: c-clef
                        //    \F: f clef
                        ,
                        1  // Postition on the staff:
                        //    1: the bottom line
                        //    5: the fifth line from the bottom
                    ]
                ]
                /*
                ,
                trans: // This defines the transposition properties of the part, if necessary.
                [
                -1 // diatonic transposition
                ,
                -2 // chromatic transposition
                ,
                0 // octave transposition
                ]
                */
            ),

            v1: // voice 1. Its elements should be constructed as an array.
            [
                // ATTENTION:
                // 1. The order of the elements is important!
                // 2. Each element of a voice should be an array!

                [\t, 120]
                // The array element with \t as the first element and a number as the second element
                // defines the tempo by the number of quarter notes per minute.
                ,

                [\f],
                // The one-element array with the following symbols defines dynamic marks:
                // - \ffff, \fff, \ff, \f,  \mf, \mp, \p,  \pp, \ppp, \pppp, \sf
                // - \s4,   \s3,  \s2, \s1, \s0, \q0, \q1, \q2, \q3,  \q4

                [\c4]
                // The array containing a scientific pitch name defines the pitch of the note.
                // - S: double sharp
                // - s: sharp
                // - (n: natural) can be ommited
                // - f: flat
                // - F: double flat
                // A quarter tone could be expressed as follows:
                // - \c5:  c5 natural
                // - \cq5: a quarter-tone raised c5
                // - \cs5: c#5
                // - \cQ5: a quarter-tone raised c#5
                // Its duration follows the last duration defined with the previous note, if any.
                // If the note is the first note of the entire notation information,
                // it follows the default value (crotchet).
                // Its dynamic mark follows the last dynamic mark defined with the previous note, if it exists.
                // If the note is the first note of the whole notation information,
                // it will follow the default value (mp).
                ,

                [\cn4],

                [62]
                // The array containing a number defines the pitch of the note.
                // The number should be an integer or a float with a single decimal ending in 0.5 as follows:
                // - 72   = \c5:  c5 natural
                // - 72.5 = \cq5: one quarter-tone raised c5
                // - 73   = \cs5: c#5
                // - 73.5 = \cQ5: one quarter-tone raised c#5
                // A float with a single decimal ending in 0.5 indicates a quarter tone.
                // The range of numbers supported is as follows:
                // - range: 0 ~ 127
                // Its duration and dynamic mark are the same as described above.
                ,

                [[64, 64.5, \g4, \gq4]]
                // A chord (notes of equal duration) should be defined as an array.
                // Its duration and dynamic mark are the same as described above.
                ,

                [67],

                [65, \w]
                // The two-element array containing a scientific pitch name followed by a duration defines
                // the pitch of the note and its duration. The following durations are ready to use:
                //
                // Durations                                  Symbols
                //
                // - double-dotted maxima:                   \Dm  \D_
                // - dotted maxima:                          \dm  \d_
                // - maxima:                                  \m   \_
                // - double-dotted longa:                    \Dl  \D0
                // - dotted longa:                           \dl  \d0
                // - longa:                                   \l   \0  0
                // - double-dotted breve:                    \Db  \D9
                // - dotted breve:                           \db  \d9
                // - breve:                                   \b   \9  9
                // - double-dotted semibreve:                \Dw  \D8
                // - dotted semibreve:                       \dw  \d8
                // - semibreve:                               \w   \8  8
                // - double-dotted minim:                    \Dh  \D7
                // - dotted minim:                           \dh  \d7
                // - minim:                                   \h   \7  7
                // - double-dotted crotchet:                 \Dq  \D6
                // - dotted crotchet:                        \dq  \d6
                // - crotchet:                                \q   \6  6
                // - double-dotted quaver:                   \De  \D5
                // - dotted quaver:                          \de  \d5
                // - quaver:                                  \e   \5  5
                // - double-dotted semiquaver:               \Dx  \D4
                // - dotted semiquaver:                      \dx  \d4
                // - semiquaver:                              \x   \4  4
                // - double-dotted demisemiquaver:           \Dt  \D3
                // - dotted demisemiquaver:                  \dt  \d3
                // - demisemiquaver:                          \t   \3  3
                // - double-dotted hemidemisemiquaver:       \Di  \D2
                // - dotted hemidemisemiquaver:              \di  \d2
                // - hemidemisemiquaver:                      \i   \2  2
                // - double-dotted semihemidemisemiquavers:  \Dn  \D1
                // - dotted semihemidemisemiquavers:         \dn  \d1
                // - semihemidemisemiquavers:                 \n   \1  1
                // - 256th:                                   '!'
                // - 512th:                                   '`'
                // - 1024th:                                  '~'
                ,

                [67, \q, \f]
                // The three-element array containing a scientific pitch name followed by
                // a duration then a dynamic mark defines the pitch of the note, its duration and dynamic mark of
                // the note.
                ,

                [67, \q, \s2],
                // Strong dynamic marks can be abbreviated as follows:
                // - ffff: s4
                // - fff:  s3
                // - ff:   s2
                // - f:    s1   <- to distinguish it with a stacatto symbol (s).

                [67, \q, \q3],
                // Quiet dynamic marks can be abbreviated as follows:
                // - pppp: q4
                // - ppp:  q3
                // - pp:   q2
                // - p:    q1   <- to distinguish it with a crotchet symbol (q).


                [68, \e, \pp, \A]
                // The four-element array containing a scientific pitch name followed by
                // a duration, a dynamic mark and an articulation defines the pitch of the note, its duration,
                // dynamic mark and articulation. The following articulations are ready to use:
                //
                // Articulations      Symbols
                // - accent:          \a
                // - strong-accent:   \A
                // - staccato:        \s
                // - staccatissimo:   \S
                // - tenuto:          \o
                // - detached-legato: \O
                ,

                [68, \e, \s2, \a, \j]
                // The five-element array containing a scientific pitch name followed by
                // a duration, a dynamic mark, an articulation and a tie status defines the pitch of the note,
                // its duration, dynamic mark, articulation and tie status.
                // The following tie states are ready to use:
                //
                // Tie status                       Symbols
                // - tie start:                       \j <- from 'join'
                // - tie stop:                        \J
                // - laissez vibrer:                  \r <- from 'let-ring'
                // - tie stop with laissez vibrer:    \R
                ,

                [68, \e, \s2, \J],

                [68, \s, \s2, \r],

                [68, \x, \j],

                [68, \e, \R],

                [68, \e, \s2, \S, \r, \u]
                // The six-element array containing a scientific pitch name followed by
                // a duration, a dynamic mark, an articulation, tie status a slur status defines
                // the pitch of the note, its duration, dynamic mark, articulation, tie status and slur status.
                // The following slur states are ready to use:
                //
                // Slur status                       Symbols
                // - slur start:                       \u <- from r in 'slur'
                // - slur stop:                        \U
                ,


                [69, \p]
                // The elements of an entry can be flexibly omitted.
                // The two-element array containing a scientific pitch name followed by an dynamic mark defines
                // the pitch of the note with its dynamic mark,
                // and its duration follows the duration of the previous note
                ,

                [71, \p]
                // The repetition of the dynamic mark will not be displayed on the score, except for sf.
                ,

                [72, \sf],

                [73, \sf],

                [74, \pp, \A, \r]
                ,

                [74, \s]
                // The two-element array containing a scientific pitch name followed by
                // an articulation defines the pitch of the note with its articulation,
                // and its duration and dynamic mark follow those of the previous note.
                ,

                [$|, \S]
                // The array containing $| defines that the pitch of the note is a repetition of
                // the previous one. Its duration and length follow those of the previous note.
                ,

                [[74, 75]],

                [$|, \h, \f, \O],

                [$|, \p, \o],

                [$|, \U],

                [$\\]
                // The array containing $\\ defines that the entry is a repetition of the previous entry.
                ,

                [[\c5, \a4, \fs4, \ds4], \x, \f],

                [$\\, \s],

                [$\\],

                [$\\],

                [$|, \7],
            ]
        ),
        p2: (
            lbl: \Contralto,
            atr: (key: [0, \none], time: \x, staves: 1, clef: [[\c, 3]]),
            v1: [
                [[\c5, \a4, \fs4, \ds4], \_, \ffff],
                [[\cq5, \aq4, \fQ4, \dQ4], \d_, \fff],
                [[\df5, \bf4, \g4, \e4], \D_, \ff]
            ]
        ),
        p3: (
            lbl: \Tenore,
            atr: (key: [0, \none], time: \x, staves: 1, clef: [[\c, 4]]),
            v1: [
                [[63.5, 60.5, 57.5, 54.5], \D0, \f],
                [[64, 61, 58, 55], \d0, \mf],
                [[64.5, 61.5, 58.5, 55.5], \0, \sf]
            ],
            v2: [
                [\r, \D0],
                [\r, \d0],
                [\r, \0]
            ]
        ),
        p4: (
            lbl: \Basso,
            atr: (key: [0, \none], time: \x, staves: 1, clef: [[\f, 4]]),
            v1: [
                [\r, \D9],
                [\r, \d9],
                [\r, 9]
            ],
            v2: [
                [[52, \g3], \D9, \mp],
                [[\e3, 55], \d9, \p],
                [[52.5, \gQ3], 9, \pp],
                [[\eq3, 56.5]]
            ]
        ),
        p5: (
            lbl: 'Clarinetto in si bemolle',
            atr: (key: [0, \none], time: \x, staves: 1, clef: [[\g, 2]], trans:[-1, -2, 0]),
            v1: [
                [72, \D8],
                [\cq5, \d8],
                [73, 8],
                [\cQ5]
            ],
            v2: [
                [67, \D8],
                [\gq4, \d8],
                [68, 8],
                [\gQ4]
            ]
        ),
        p6: (
            lbl: 'Violino',
            atr: (key: [0, \none], time: \x, staves: 1, clef: [[\g, 2]]),
            v1: [
                [72, \D8],
                [\cq5, \d8],
                [73, 8],
                [\cQ5]
            ],
            v2: [
                [67, \D8],
                [\gq4, \d8],
                [68, 8],
                [\gQ4]
            ]
        ),
        p7: (
            lbl: \Viola,
            atr: (key: [0, \none], time: \x, staves: 1, clef: [[\c, 3]]),
            v1: [
                [\cq4, \D7, \ppp],
                [\dq4, \d7, \pppp],
                [[61.5, \dq4, \cq4], 7]
            ]
        ),
        p8: (
            lbl: \Violoncello,
            atr: (key: [0, \none], time: \x, staves: 1, clef: [[\f, 4]]),
            v1: [
                [\c3, \D6, \f],
                [\c3, \d6, \f],
                [\c3, 6, \f]
            ]
        ),
        p9: (
            lbl: \Contrabass,
            atr: (key: [0, \none], time: \x, staves: 1, clef: [[\f, 4]], trans: [0, 0, -1]),
            v1: [
                [\c3, \D6, \f],
                [\c3, \d6, \f],
                [\c3, 6, \f]
            ]
        ),
        p10: (
            lbl: 'Piano 1',
            atr: (key: [0, \none], time: \x, staves: 2, clef: [[\g, 2], [\f, 4]]),
            v1: [
                [[\c5, \e5, \g5], \D5, \f],
                [\ef5, \d5],
                [\c5, \5],
                [$|],
                [$|, \D4],
                [$|, \d4],
                [$|, \4],
                [[\d5, 76], \D3],
                [$|, \d3],
                [$|, \3],
                [[\d4, 65, 68], \D2],
                [$|, \d2],
                [$|, \2]/*,
                [[69, 74, 88], \D1, \sf],
                [$|, \d1],
                [$|, \1],
                [$|, '!'],
                [$|, '`'],
                [$|, '~']*/
            ],
            v2: [
                [\cF4, \h],
                [\cf3, \h]
            ]
        ),
        p11: (
            lbl: 'Piano 2',
            atr: (
                key: [0, \none],
                time: \x,
                staves: 4,
                clef: [[\g, 2, 2], [\g, 2], [\f, 4], [\f, 4, -2]]
            ),
            v1: [
                [[\a7, \a6], [\e, 3, 2, \e]],
                [$|, [\e]],
                [$|, [5, \]],
                [[\af7, \as6], [\e, 3, 2, \e]],
                [$|, [[\x, 3, 2, \x]]],
                [$|, [[\x]]],
                [$|, [[\x, \]]],
                [$|, [\e, \]],
                [$|, [\e, 5, 4, \e]],
                [$|, [[\e, 3, 2, \e]]],
                [$|, [[\q, \]]],
                [$|, [\q, \]]
            ],
            v2: [
                [[\a5, \a4], [\x, 5, 4, \x]],
                [$|, [\x]],
                [$|, [4]],
                [$|, [\x]],
                [$|, [4, \]],
                [[\af5, \a4], [\x, 6, 4, \x]],
                [$|, [\x]],
                [$|, [5]],
                [$|, [\x]],
                [$|, [4, \]]
            ],
            v3:
            [
                [[\a3, \a2], 6]
            ],
            v4: [
                [[\a1, \a0]]
            ],
        )
    )
];

~exportXML.(~score1, "~/Downloads/multiple instruments.musicxml".standardizePath, 'MuseScore 4')
)

3. Example 2: simple tuplets

(
~score2 = [
    (   title: 'untitled', composer: 'me', rights: '©'),
    (
        bar: 1,
        p1: (
            lbl: \,
            atr: (
                key: [1, \major],
                time: [4, 4],
                staves: 4,
                clef: [[\g, 2, 2], [\g, 2], [\f, 4], [\f, 4, -2]]
            ),
            v1: [
                [\t, 120],
                [\q4],
                [96],
                [[\a7, \g7], \dh],
                [\a6, [\e, 3, 2, \e], \pppp],
                [$|, [\e], \s4],
                [$|, [5, \]],
                [\r, \q],
                [\r, \h]
            ],
            v2: [
                [\a4, [\x, 5, 4, \x]],
                [$|, [\x]],
                [$|, [4]],
                [$|, [\x], \sf],
                [$|, [4, \], \sf],
                [\r, \dh]
            ],
            v3: [
                [\a3, 6],
                [\a3, \sf],
                [\r, \dh]
            ],
            v4: [
                [\a0],
                [\a0, \p],
                [\a0, \mf],
                [\r, \dh]
            ]
        )
    ),
    (
        bar: 2,
        p1: (
            v1: [
                [\s1],
                [\g6, [\e, 3, 2, \e]],
                [$|, [\e]],
                [$|, [5, \]],
                [\r, \dh]
            ],
            v2: [
                [\a4, [\x, 5, 4, \x]],
                [$|, [\x]],
                [$|, [\x]],
                [$|, [\e, \]],
                [\r, 5],
                [\r, \q],
                [\r, \h]
            ],
            v3: [
                [\a3, \d6],
                [\r, \q]
            ],
            v4: [
                [\a0],
                [\r, \dh]
            ]
        )
    )
];

~exportXML.(~score2, "~/Downloads/simple tuplets.musicxml".standardizePath, 'MuseScore 4')
)

4. Example 3: 12-tone matrix generation and playback

(
~matrix_12tone = { |array|
    var matrix = 12.collect { |i| array[i]; array - (array[i] % 12) };
    matrix.do { |item| item.replace(11, \e).replace(10, \t).postln }
};

~matrix = ~matrix_12tone.((0..11).scramble) + 72;

~score3 = [(title: '12-tone series matrix', composer: 'randomised', right: '©')] ++
~matrix.collect { |series, index|
    if (index == 0) {
        (
            bar: index + 1,
            p1: (
                lbl: '',
                atr: (key: [0, \none], time: \x, staves: 1, clef: [[\g, 2]]),
                v1: series.collect { |aNote| [aNote, \w] }
            )
        )
    } {
        series.postln;
        (
            bar: index + 1,
            p1: (v1: series.collect { |aNote| [aNote, \w] })
        )
    }
};

fork{
    ~score3[1..].do { |amusicXMLelement|
        var bar, notes;
        bar = amusicXMLelement[\bar];
        notes = amusicXMLelement[\p1][\v1];
        notes.do { |noteOrchord|
            var pitch, duration;
            # pitch, duration = noteOrchord;
            duration = (w: 0.4/*, h: \w / 2, q: \w / 4*/)[duration];
            ("bar" + bar ++ ":" + noteOrchord).postln;
            (midinote: pitch, dur: duration).play;
            duration.wait
        }
    }
};

~exportXML.(~score3, "~/Downloads/12-tone series matrix.musicxml".standardizePath, 'MuseScore 4')
)

5. Example 4: Creating and playing a random composition for an instrument

(
var metronome, notesOrRests, dynamics, noteTypes, title = 'random an instrument';
metronome = 240;
notesOrRests = { [{ ((21..108)).choose } ! (1..4).choose, \r].choose } ! 100; // \r: rest
// <- ! 100: increasing the number can results in the following error:
// Interpreter has crashed or stopped forcefully. [Exit code: 11]

dynamics = (ffff: 115, fff: 103, ff:91, f:79, mf: 67, mp: 55, p: 43, pp: 31, ppp: 19, pppp: 7, sf: 127);
noteTypes = (/*Dm: 56, dm: 48, m: 32, Dl: 28, dl: 24, l: 16, Db: 14, db: 12, b: 8, Dw: 7, dw: 6,*/
    w: 4, Dh: 3.5, dh: 3, h: 2, Dq: 1.75, dq: 1.5, q: 1,
    De: 0.875, de: 0.75, e: 0.5, Dx: 0.4375, dx: 0.375, x: 0.25/*, Ds: 0.021875, ds: 0.1875, s: 0.125,
Df: 0.109375, df: 0.09375, f: 0.0625*/);

~score4 = [
    (title: title, composer: 'randomised', right: '©'),
    (
        bar: 1,
        p1: (
            lbl: '',
            atr: (key: [0, \none], time: \x, staves: 4, clef: [[\g, 2, 2], [\g, 2], [\f, 4], [\f, 4, -2]]),
            v1: []
        )
    )
];

notesOrRests.do { |aNotesOrRest, index|
    var musicXMLelement = switch (aNotesOrRest.class.asSymbol, // symbol: rest, array: notes
        \Array,    { [aNotesOrRest, noteTypes.keys.choose, dynamics.keys.choose] },
        \Symbol, { [aNotesOrRest, noteTypes.keys.choose] }
    );
    ~score4[1][\p1][\v1] = ~score4[1][\p1][\v1].add(musicXMLelement)
};

~score4[1][\p1][\v1] = ~score4[1][\p1][\v1].insert(0, [\t, metronome]);

~exportXML.(~score4, ("~/Downloads" +/+ title ++".musicxml").standardizePath, 'MuseScore 4');

fork{
    (1 .. ~score4[1][\p1][\v1].size - 1).do { |index|
        var thisXMLelement, aNoteOrChordOrRest, duration, velocity;

        thisXMLelement = ~score4[1][\p1][\v1][index];

        (    "\n" ++ index ++ ":" + thisXMLelement + thisXMLelement.class).postln;

        if (thisXMLelement.size == 3) {
            # aNoteOrChordOrRest, duration, velocity = thisXMLelement
        } {
            if (thisXMLelement[0] == \r) {
                # aNoteOrChordOrRest, duration = thisXMLelement;
            }
        };
        (    "\taNoteOrChordOrRest:" + aNoteOrChordOrRest + aNoteOrChordOrRest.class).postln;
        (    "\tvelocity:" + velocity + velocity.class).postln;
        duration = noteTypes[duration];
        velocity = dynamics[velocity];
        if (velocity == nil) { velocity = 0 };
        (    "\tvelocity to amp:" + velocity + velocity.class).postln;
        (    "\tduration:" + duration + duration.class).postln;
        (midinote: aNoteOrChordOrRest, amp: velocity.linlin(0, 127, -48, -12).dbamp).play;
        (duration / (metronome / 60)).wait;
    }
}
)

6. Example 5: Creating and playing a random composition for two instruments

(
var metronome, makeNotesOrRest, dynamics, noteTypes, makeDynamic, makeNotetype, title = 'random two instruments';
metronome = 120;
makeNotesOrRest = {|lowest, highest| [{ ((lowest..highest)).choose } ! (1..4).choose, \r].choose }; // \r: rest
dynamics = (ffff: 115, fff: 103, ff:91, f:79, mf: 67, mp: 55, p: 43, pp: 31, ppp: 19, pppp: 7, sf: 127);
makeDynamic = { dynamics.keys.choose };
noteTypes = (/*Dm: 56, dm: 48, m: 32, Dl: 28, dl: 24, l: 16, Db: 14, db: 12, b: 8, Dw: 7, dw: 6,*/
    w: 4, Dh: 3.5, dh: 3, h: 2, Dq: 1.75, dq: 1.5, q: 1,
    De: 0.875, de: 0.75, e: 0.5, Dx: 0.4375, dx: 0.375, x: 0.25/*, Ds: 0.021875, ds: 0.1875, s: 0.125,
Df: 0.109375, df: 0.09375, f: 0.0625*/);
makeNotetype = { noteTypes.keys.choose };

~score5 = [
    (title: title, composer: 'randomised', right: '©'),
    (
        bar: 1,
        p1: (
            lbl: '',
            atr: (key: [0, \none], time: \x, staves: 1, clef: [[\g, 2]]),
            v1: []
        ),
        p2: (
            lbl: '',
            atr: (key: [0, \none], time: \x, staves: 1, clef: [[\f, 4]]),
            v1: []
        )
    )
];

100.do
// <- 100.do
// : increasing the number can results in the following error:
// Interpreter has crashed or stopped forcefully. [Exit code: 11]
{
    var makeMusic = { |lowest, highest|
        var    musicXMLelement = makeNotesOrRest.(lowest, highest);
        switch (musicXMLelement.class.asSymbol, // symbol: rest, array: notes
            \Array,    { [musicXMLelement, makeNotetype.(), makeDynamic.()] },
            \Symbol, { [musicXMLelement, makeNotetype.()] }
        )
    };
    ~score5[1][\p1][\v1] = ~score5[1][\p1][\v1].add(makeMusic.(60, 84));
    ~score5[1][\p2][\v1] = ~score5[1][\p2][\v1].add(makeMusic.(36, 60));
};

~score5[1][\p1][\v1] = ~score5[1][\p1][\v1].insert(0, [\t, metronome]);

~exportXML.(~score5, ("~/Downloads" +/+ title ++".musicxml").standardizePath, 'MuseScore 4');

~playMusic = { |player, pan, tab = ""|
    fork {
        (~score5[1][player][\v1].size).do { |index|
            var thisXMLelement, aNoteOrChordOrRest, duration, velocity;

            thisXMLelement = ~score5[1][player][\v1][index];

            (    "\n" ++ tab ++ index ++ ":" + thisXMLelement + thisXMLelement.class).postln;

            if (thisXMLelement[0] != \t) {
                if (thisXMLelement.size == 3) {
                    # aNoteOrChordOrRest, duration, velocity = thisXMLelement
                } {
                    if (thisXMLelement[0] == \r) {
                        # aNoteOrChordOrRest, duration = thisXMLelement;
                    }
                };
                (    tab ++ "\taNoteOrChordOrRest:" + aNoteOrChordOrRest + aNoteOrChordOrRest.class).postln;
                (    tab ++ "\tvelocity:" + velocity + velocity.class).postln;
                duration = noteTypes[duration];
                velocity = dynamics[velocity];
                if (velocity == nil) { velocity = 0 };
                (    tab ++ "\tvelocity to amp:" + velocity + velocity.class).postln;
                (    tab ++ "\tduration:" + duration + duration.class).postln;
                (midinote: aNoteOrChordOrRest, amp: velocity.linlin(0, 127, -36, -12).dbamp, pan: pan).play;
                (duration / (metronome / 60)).wait;
            }
        }
    }
};

~playMusic.(\p1, -0.6);
~playMusic.(\p2, 0.6, "\t\t\t\t\t\t")
)





2 Likes