One for All: Difference between revisions

From Xenharmonic Wiki
Jump to navigation Jump to search
Xenjacob (talk | contribs)
No edit summary
BudjarnLambeth (talk | contribs)
m Categorised this uncategorised page
 
(4 intermediate revisions by one other user not shown)
Line 1: Line 1:
Rough multitrack recording by Jacob Barton, http://oneforall.ytmnd.com
Score in sagittal: [[File:SS01_One_for_All.pdf]]


Code tutorial (with assignment for xenharmonic campers) in ChucK (save as a .ck file to use in ChucK):
Premiere recording at Xenharmonic Praxis Summer Camp 2011, Hillsboro, WV: http://micro.soonlabel.com/0-praxis/audio/July/july_group_5a_one_for_all2.mp3
<nowiki>/* Sagittal Songbook 01
One for All
by Ryan Stickney


A four-part round in just intonation, in 11/4 time
Second recording at XPSC 2011: https://youtu.be/S62yVU1pspQ?t=1257
Coded by xenjacob Jan. 2020


The implementation is basic, and shared in this way both to introduce
Performance recording at Xenharmonic Praxis Summer Camp 2013, Salem, NH: https://jacobbarton.bandcamp.com/track/one-for-all
some basics of ChucK and to illustrate the
degree of 'grunt work' which may (not must) accompany any work of art.


ASSIGNMENT FOR XENCAMPERS:
Multitrack recording by Jacob Barton, http://oneforall.ytmnd.com
1. Get this code to work on your setup! Save this text as a .ck file.
If you are running miniAudicle, all you have to do then is
'Start Virtual Machine' and then 'Add Shred'.
2. Try modifying 1/1 pitch and/or tempo (read thru the comments below for how)
3. Learn the song!
4. Make a rough recording of yourself singing along to patch. (Change anything, have phun with it)
5. (Optional) Think up a single alteration that would make this patch
'more musical', and send it to xenjacob. No need to know how to code it yourself.


The melody line is first encoded as a 2D array corresponding
Code tutorial (with assignment for xenharmonic campers) in [http://chuck.cs.princeton.edu the ChucK environment] (copy and save the below text as a .ck file to use in ChucK):
to pitch and rhythm values
<nowiki>/* Sagittal Songbook 01
[[ pitch, rhythm ], ...]
    One for All
 
    by Ryan Stickney
This kind of score entry is labor-intensive, but a rather good match to the
 
Sagittal Songbook project due to the brevity of most of the songs.
  A four-part round in just intonation, in 11/4 time
 
  Coded by xenjacob Jan. 2020
Pitches are in JI intervals in relation to the defined 1/1 (notated C)
 
A decimal point in the fraction forces ChucK to do non-integer
  The implementation is basic, and shared in this way both to introduce
arithmetic to create a floating-point value (otherwise it will e.g. compute
  some basics of ChucK and to illustrate the
4/3 as 1 remainder 1 and discard the remainder)
  degree of 'grunt work' which may (not must) accompany any work of art.
 
 
Rhythms are declared in relation to the value of a quarter note,
  ASSIGNMENT FOR XENCAMPERS:
assigned here to the value 1 (half note = 2, dotted half = 3, etc.)
  1. Get this code to work on your setup! Save this text as a .ck file.
*/
  If you are running miniAudicle, all you have to do then is
 
  'Start Virtual Machine' and then 'Add Shred'.
[
  2. Try modifying 1/1 pitch and/or tempo (read thru the comments below for how)
[ 1/1., 2 ], // All
  3. Learn the song!
[ 3/2., 2 ], // things
  4. Make a rough recording of yourself singing along to patch. (Change anything, have phun with it)
[ 2/1., 1 ], // wing-
  5. (Optional) Think up a single alteration that would make this patch
[ 7/4., 1], // -ed
  'more musical', and send it to xenjacob. No need to know how to code it yourself.
[ 3/2., 1 ], // are
 
[ 4/3., 2 ], // made
  The melody line is first encoded as a 2D array corresponding
[ 5/4., 2 ], // for
  to pitch and rhythm values
[ 3/2., 2 ], // jump-
  [[ pitch, rhythm ], ...]
[ 2/1., 2 ], // -ing
 
[ 5/2., 1 ], // in-
  This kind of score entry is labor-intensive, but a rather good match to the
[ 9/4., 1 ], // -to
  Sagittal Songbook project due to the brevity of most of the songs.
[ 2/1., 1 ], // the
 
[ 7/4., 1 ], // sky__
  Pitches are in JI intervals in relation to the defined 1/1 (notated C)
[ 7/4., 2 ], // (bend)
  A decimal point in the fraction forces ChucK to do non-integer
[ 2/1., 5/3. ], // ____.
  arithmetic to create a floating-point value (otherwise it will e.g. compute
// implementing a rhythmic breath or 'hiccup' at the end of each phrase
  4/3 as 1 remainder 1 and discard the remainder)
// equal to two-thirds of a beat.
 
 
  Rhythms are declared in relation to the value of a quarter note,
[ 5/4., 2 ], // Fall-
  assigned here to the value 1 (half note = 2, dotted half = 3, etc.)
[ 5/4., 2 ], // -ing
  */
[ 4/3., 1 ], // brings
 
[ 9/8., 1 ], // no
  [
[ 5/4., 1 ], // di-
  [ 1/1., 2 ], // All
[ 2/1., 2 ], // -sas-
  [ 3/2., 2 ], // things
[ 7/4., 2 ], // -ter
  [ 2/1., 1 ], // wing-
[ 15/8., 2 ], // when
  [ 7/4., 1], // -ed
[ 5/4., 2 ], // you
  [ 3/2., 1 ], // are
[ 3/2., 3 ], // can
  [ 4/3., 2 ], // made
[ 4/3., 1 ], // fly_
  [ 5/4., 2 ], // for
[ 4/3., 2 ], // (bend)
  [ 3/2., 2 ], // jump-
[ 5/4., 5/3. ], // __.
  [ 2/1., 2 ], // -ing
 
  [ 5/2., 1 ], // in-
[ 3/2., 2 ], // Calls
  [ 9/4., 1 ], // -to
[ 2/1., 2 ], // sing
  [ 2/1., 1 ], // the
[ 3/2., 3 ], // birds
  [ 7/4., 1 ], // sky__
[ 9/8., 2 ], // to
  [ 7/4., 2 ], // (bend)
[ 1/1., 2 ], // each
  [ 2/1., 5/3. ], // ____.
[ 9/8., 1 ], // o-
  // implementing a rhythmic breath or 'hiccup' at the end of each phrase
[ 5/4., 1 ], // -ther
  // equal to two-thirds of a beat.
[ 11/8., 1 ], // but
 
[ 3/2., 1], // who
  [ 5/4., 2 ], // Fall-
[ 2/1., 3 ], // knows
  [ 5/4., 2 ], // -ing
[ 9/4., 1 ], // why?__
  [ 4/3., 1 ], // brings
[ 9/4., 2 ], // __(bend)
  [ 9/8., 1 ], // no
[ 2/1., 5/3.], // ___
  [ 5/4., 1 ], // di-
 
  [ 2/1., 2 ], // -sas-
[ 2/1., 4], // Fly-
  [ 7/4., 2 ], // -ter
[ 7/4., 3 ], // -ing
  [ 15/8., 2 ], // when
[ 4/3., 2 ], // looks
  [ 5/4., 2 ], // you
[ 3/2., 2 ], // fun;
  [ 3/2., 3 ], // can
[ 3/2., 4 ], // I'm
  [ 4/3., 1 ], // fly_
[ 1/1., 1 ], // will-
  [ 4/3., 2 ], // (bend)
[ 9/8., 1 ], // -ing
  [ 5/4., 5/3. ], // __.
[ 5/4., 1 ], // to
 
[ 1/1., 4.+2/3. ] // try.
  [ 3/2., 2 ], // Calls
 
  [ 2/1., 2 ], // sing
] @=> float score[][]; // "@=>" is the assignment operator for arrays.
  [ 3/2., 3 ], // birds
 
  [ 9/8., 2 ], // to
// Since there are only a few glissandi in the score,
  [ 1/1., 2 ], // each
// let's collect the index #'s of the notes which gliss
  [ 9/8., 1 ], // o-
// into an array "bends":
  [ 5/4., 1 ], // -ther
 
  [ 11/8., 1 ], // but
[ 13, 26, 39 ] @=> int bends[];
  [ 3/2., 1], // who
 
  [ 2/1., 3 ], // knows
// one_one will define the 1/1 frequency in Hz
  [ 9/4., 1 ], // why?__
// **CHANGE THIS** to try in different keys!
  [ 9/4., 2 ], // __(bend)
221 => float one_one;
  [ 2/1., 5/3.], // ___
// 261.6 is approximately concert C pitch
 
// 240 tunes to electrical hum (in the Americas and Asia anyway)
  [ 2/1., 4], // Fly-
// B flat (233) has also been traditionally used in this round.
  [ 7/4., 3 ], // -ing
 
  [ 4/3., 2 ], // looks
// 'pulse' wil define the time duration of a quarter note
  [ 3/2., 2 ], // fun;
// **CHANGE THIS** to try different tempi!
  [ 3/2., 4 ], // I'm
556::ms => dur pulse;
  [ 1/1., 1 ], // will-
// the :: must separate the numerical value and the duration unit
  [ 9/8., 1 ], // -ing
// (which can be samp, ms, second, minute, hour, day, or week)
  [ 5/4., 1 ], // to
 
  [ 1/1., 4.+2/3. ] // try.
// PlayScore is a function which will read the score (any score specified
 
// in the same manner, actually), note by note, into
  ] @=> float score[][]; // "@=>" is the assignment operator for arrays.
// a dedicated triangle wave oscillator.
 
 
  // Since there are only a few glissandi in the score,
// But Wait!
  // let's collect the index #'s of the notes which gliss
// Musicality Mod 1 (suggested by Thomas): the ability to play in other registers.
  // into an array "bends":
// PlayScore will take an additional argument, specifying the number of  
 
// octaves offset (-1 for octave down, 0 for at pitch, 1 for octave up, etc.
  [ 13, 26, 39 ] @=> int bends[];
fun void PlayScore( float play[][], int octave_shift )
 
{
  // one_one will define the 1/1 frequency in Hz
    TriOsc t => dac; // direct link to the digital audio converter (soundcard)
  // **CHANGE THIS** to try in different keys!
    0.25 => t.gain; // range [0,1] - let's leave room for 4 voices here
  221 => float one_one;
    // (digital distortion otherwise...which actually makes some really neat effects, try it!
  // 261.6 is approximately concert C pitch
   
  // 240 tunes to electrical hum (in the Americas and Asia anyway)
    // loop iterates thru the play array, one note entry at a time
  // B flat (233) has also been traditionally used in this round.
    for( 0 => int i; i < play.cap(); i++)
 
    {
  // 'pulse' wil define the time duration of a quarter note
        // read the array, change the frequency
  // **CHANGE THIS** to try different tempi!
        play[i][0] * one_one * Math.pow(2, octave_shift) => t.freq;
  556::ms => dur pulse;
       
  // the :: must separate the numerical value and the duration unit
        // glissando code
  // (which can be samp, ms, second, minute, hour, day, or week)
        // hard-coded to 3 total glisses, because ChucK doesn't
 
        // seem to have any built-in array searching
  // PlayScore is a function which will read the score (any score specified
        if( bends[0] == i || bends[1] == i || bends[2] == i )
  // in the same manner, actually), note by note, into
        {
  // a dedicated triangle wave oscillator.
            // divides the length of the rhythm of that note
 
            // into 366 parts, because, hey, leap year!
  // But Wait!
            366 => float rhdiv;
  // Musicality Mod 1 (suggested by Thomas): the ability to play in other registers.
            for( 0 => int j; j <= rhdiv; j++)
  // PlayScore will take an additional argument, specifying the number of
            {
  // octaves offset (-1 for octave down, 0 for at pitch, 1 for octave up, etc.
                // one_one * play[i][0] *
  fun void PlayScore( float play[][], int octave_shift )
                //  Math.pow( (play[i+1][0]/play[i][0]) , j/rhdiv ) => t.freq;
  {
                // Above code divides the glissando down by equal (logarithmic) steps,
      TriOsc t => dac; // direct link to the digital audio converter (soundcard)
                // Doesn't sound 'natural' to me,
      0.25 => t.gain; // range [0,1] - let's leave room for 4 voices here
                // Let's try equal-frequency steps:
      // (digital distortion otherwise...which actually makes some really neat effects, try it!
                ((play[i+1][0] - play[i][0])*one_one/rhdiv*j + play[i][0]*one_one) * Math.pow(2, octave_shift) => t.freq;
     
                 pulse*play[i][1]/rhdiv => now;
      // loop iterates thru the play array, one note entry at a time
                // I still wasn't happy with it,
      for( 0 => int i; i < play.cap(); i++)
                // but hey, "Publish or die." -- Rob Scott
      {
            }
          // read the array, change the frequency
        }
          play[i][0] * one_one * Math.pow(2, octave_shift) => t.freq;
        // this code is executed in non-glissando case
         
        else {
          // glissando code
            // chucking a duration to now advances time
          // hard-coded to 3 total glisses, because ChucK doesn't
            // by that amount within the shred
          // seem to have any built-in array searching
            pulse*play[i][1] => now;
          if( bends[0] == i || bends[1] == i || bends[2] == i )
        }
          {
    }
              // divides the length of the rhythm of that note
}
              // into 366 parts, because, hey, leap year!
 
              366 => float rhdiv;
PlayScore( score, 0); // Calling the function once will play thru the melody once.
              for( 0 => int j; j <= rhdiv; j++)
// See if you can add multiple shreds of this at just the right time to play in round!
              {
// Try alternating lower and higher octaves!
                  // one_one * play[i][0] *
/*
                  //  Math.pow( (play[i+1][0]/play[i][0]) , j/rhdiv ) => t.freq;
// remove lines 169 and 205, AND comment/remove line 165, to unlock...
                  // Above code divides the glissando down by equal (logarithmic) steps,
// CHAPTER TWO - Programmed Polyphony
                  // Doesn't sound 'natural' to me,
// a function to hang out between successive entries
                  // Let's try equal-frequency steps:
fun void waitLine() {
                  ((play[i+1][0] - play[i][0])*one_one/rhdiv*j + play[i][0]*one_one) * Math.pow(2, octave_shift) => t.freq;
    (22.+2/3.)*pulse => now;
                  pulse*play[i][1]/rhdiv => now;
}
                  // I still wasn't happy with it,
// to execute functions 'in series', simply call them, as  
                  // but hey, "Publish or die." -- Rob Scott
// to execute 'in parallel', use 'spork~' to create breakoff shreds.
                 }
// 'spork a shred' > 'fork a thread', good one Ge Wang...
          }
 
          // this code is executed in non-glissando case
// the below code initiates five separate shreds
          else {
// to simulate five round entries
              // chucking a duration to now advances time
 
              // by that amount within the shred
spork~ PlayScore ( score, 0 ); // first entry
              pulse*play[i][1] => now;
waitLine();
          }
spork~ PlayScore ( score, 1 );
      }
waitLine();
  }
spork~ PlayScore ( score, 0 );
 
waitLine();
  PlayScore( score, 0); // Calling the function once will play thru the melody once.
spork~ PlayScore ( score, 1 );
  // See if you can add multiple shreds of this at just the right time to play in round!
waitLine();
  // Try alternating lower and higher octaves!
// now check this out
  /*
// for the last entry, we gonna do a 'Meno Mosso' (slower tempo)
  // remove lines 169 and 205, AND comment/remove line 165, to unlock...
// we change ONE VARIABLE, and all four lines follow!
  // CHAPTER TWO - Programmed Polyphony
// if we had passed the pulse as an argument to each function instead of
  // a function to hang out between successive entries
// using this sort of global variable, this wouldn't work.
  fun void waitLine() {
1.1 *=> pulse; // multiply value of pulse by 1.1 and re-assign
      (22.+2/3.)*pulse => now;
spork~ PlayScore ( score, 0 ); // final entry
  }
// now, let the round play out;
  // to execute functions 'in series', simply call them, as  
// if the main shred of this script terminated early,
  // to execute 'in parallel', use 'spork~' to create breakoff shreds.
// it would automatically terminate any child shreds still running
  // 'spork a shred' > 'fork a thread', good one Ge Wang...
waitLine();
 
waitLine();
  // the below code initiates five separate shreds
waitLine();
  // to simulate five round entries
waitLine();
 
/*</nowiki>
  spork~ PlayScore ( score, 0 ); // first entry
  waitLine();
  spork~ PlayScore ( score, 1 );
  waitLine();
  spork~ PlayScore ( score, 0 );
  waitLine();
  spork~ PlayScore ( score, 1 );
  waitLine();
  // now check this out
  // for the last entry, we gonna do a 'Meno Mosso' (slower tempo)
  // we change ONE VARIABLE, and all four lines follow!
  // if we had passed the pulse as an argument to each function instead of
  // using this sort of global variable, this wouldn't work.
  1.1 *=> pulse; // multiply value of pulse by 1.1 and re-assign
  spork~ PlayScore ( score, 0 ); // final entry
  // now, let the round play out;
  // if the main shred of this script terminated early,
  // it would automatically terminate any child shreds still running
  waitLine();
  waitLine();
  waitLine();
  waitLine();
  /*</nowiki>
[[Category:Composition]]
[[Category:Sagittal notation]]
[[Category:Scores]]
[[Category:Listen]]

Latest revision as of 10:06, 1 May 2023

Score in sagittal: File:SS01 One for All.pdf

Premiere recording at Xenharmonic Praxis Summer Camp 2011, Hillsboro, WV: http://micro.soonlabel.com/0-praxis/audio/July/july_group_5a_one_for_all2.mp3

Second recording at XPSC 2011: https://youtu.be/S62yVU1pspQ?t=1257

Performance recording at Xenharmonic Praxis Summer Camp 2013, Salem, NH: https://jacobbarton.bandcamp.com/track/one-for-all

Multitrack recording by Jacob Barton, http://oneforall.ytmnd.com

Code tutorial (with assignment for xenharmonic campers) in the ChucK environment (copy and save the below text as a .ck file to use in ChucK):

/* Sagittal Songbook 01
    One for All
    by Ryan Stickney
   
   A four-part round in just intonation, in 11/4 time
   Coded by xenjacob Jan. 2020
   
   The implementation is basic, and shared in this way both to introduce
   some basics of ChucK and to illustrate the
   degree of 'grunt work' which may (not must) accompany any work of art.
   
   ASSIGNMENT FOR XENCAMPERS:
   1. Get this code to work on your setup! Save this text as a .ck file.
   If you are running miniAudicle, all you have to do then is
   'Start Virtual Machine' and then 'Add Shred'.
   2. Try modifying 1/1 pitch and/or tempo (read thru the comments below for how)
   3. Learn the song!
   4. Make a rough recording of yourself singing along to patch. (Change anything, have phun with it)
   5. (Optional) Think up a single alteration that would make this patch
   'more musical', and send it to xenjacob. No need to know how to code it yourself.
   
   The melody line is first encoded as a 2D array corresponding
   to pitch and rhythm values
   [[ pitch, rhythm ], ...]
   
   This kind of score entry is labor-intensive, but a rather good match to the
   Sagittal Songbook project due to the brevity of most of the songs.
   
   Pitches are in JI intervals in relation to the defined 1/1 (notated C)
   A decimal point in the fraction forces ChucK to do non-integer
   arithmetic to create a floating-point value (otherwise it will e.g. compute
   4/3 as 1 remainder 1 and discard the remainder)
   
   Rhythms are declared in relation to the value of a quarter note,
   assigned here to the value 1 (half note = 2, dotted half = 3, etc.)
   */
   
   [
   [ 1/1., 2 ], // All
   [ 3/2., 2 ], // things
   [ 2/1., 1 ], // wing-
   [ 7/4., 1], // -ed
   [ 3/2., 1 ], // are
   [ 4/3., 2 ], // made
   [ 5/4., 2 ], // for
   [ 3/2., 2 ], // jump-
   [ 2/1., 2 ], // -ing
   [ 5/2., 1 ], // in-
   [ 9/4., 1 ], // -to
   [ 2/1., 1 ], // the
   [ 7/4., 1 ], // sky__
   [ 7/4., 2 ], // (bend)
   [ 2/1., 5/3. ], // ____.
   // implementing a rhythmic breath or 'hiccup' at the end of each phrase
   // equal to two-thirds of a beat.
   
   [ 5/4., 2 ], // Fall-
   [ 5/4., 2 ], // -ing
   [ 4/3., 1 ], // brings
   [ 9/8., 1 ], // no
   [ 5/4., 1 ], // di-
   [ 2/1., 2 ], // -sas-
   [ 7/4., 2 ], // -ter
   [ 15/8., 2 ], // when
   [ 5/4., 2 ], // you
   [ 3/2., 3 ], // can
   [ 4/3., 1 ], // fly_
   [ 4/3., 2 ], // (bend)
   [ 5/4., 5/3. ], // __.
   
   [ 3/2., 2 ], // Calls
   [ 2/1., 2 ], // sing
   [ 3/2., 3 ], // birds
   [ 9/8., 2 ], // to
   [ 1/1., 2 ], // each
   [ 9/8., 1 ], // o-
   [ 5/4., 1 ], // -ther
   [ 11/8., 1 ], // but
   [ 3/2., 1], // who
   [ 2/1., 3 ], // knows
   [ 9/4., 1 ], // why?__
   [ 9/4., 2 ], // __(bend)
   [ 2/1., 5/3.], // ___
   
   [ 2/1., 4], // Fly-
   [ 7/4., 3 ], // -ing
   [ 4/3., 2 ], // looks
   [ 3/2., 2 ], // fun;
   [ 3/2., 4 ], // I'm
   [ 1/1., 1 ], // will-
   [ 9/8., 1 ], // -ing
   [ 5/4., 1 ], // to
   [ 1/1., 4.+2/3. ] // try.
   
   ] @=> float score[][]; // "@=>" is the assignment operator for arrays.
   
   // Since there are only a few glissandi in the score,
   // let's collect the index #'s of the notes which gliss
   // into an array "bends":
   
   [ 13, 26, 39 ] @=> int bends[];
   
   // one_one will define the 1/1 frequency in Hz
   // **CHANGE THIS** to try in different keys!
   221 => float one_one;
   // 261.6 is approximately concert C pitch
   // 240 tunes to electrical hum (in the Americas and Asia anyway)
   // B flat (233) has also been traditionally used in this round.
   
   // 'pulse' wil define the time duration of a quarter note
   // **CHANGE THIS** to try different tempi!
   556::ms => dur pulse;
   // the :: must separate the numerical value and the duration unit
   // (which can be samp, ms, second, minute, hour, day, or week)
   
   // PlayScore is a function which will read the score (any score specified
   // in the same manner, actually), note by note, into
   // a dedicated triangle wave oscillator.
   
   // But Wait!
   // Musicality Mod 1 (suggested by Thomas): the ability to play in other registers.
   // PlayScore will take an additional argument, specifying the number of 
   // octaves offset (-1 for octave down, 0 for at pitch, 1 for octave up, etc.
   fun void PlayScore( float play[][], int octave_shift )
   {
       TriOsc t => dac; // direct link to the digital audio converter (soundcard)
       0.25 => t.gain; // range [0,1] - let's leave room for 4 voices here
       // (digital distortion otherwise...which actually makes some really neat effects, try it!
       
       // loop iterates thru the play array, one note entry at a time
       for( 0 => int i; i < play.cap(); i++)
       {
           // read the array, change the frequency
           play[i][0] * one_one * Math.pow(2, octave_shift) => t.freq;
           
           // glissando code
           // hard-coded to 3 total glisses, because ChucK doesn't
           // seem to have any built-in array searching
           if( bends[0] == i || bends[1] == i || bends[2] == i )
           {
               // divides the length of the rhythm of that note
               // into 366 parts, because, hey, leap year!
               366 => float rhdiv;
               for( 0 => int j; j <= rhdiv; j++)
               {
                   // one_one * play[i][0] *
                   //  Math.pow( (play[i+1][0]/play[i][0]) , j/rhdiv ) => t.freq;
                   // Above code divides the glissando down by equal (logarithmic) steps,
                   // Doesn't sound 'natural' to me,
                   // Let's try equal-frequency steps:
                   ((play[i+1][0] - play[i][0])*one_one/rhdiv*j + play[i][0]*one_one) * Math.pow(2, octave_shift) => t.freq;
                   pulse*play[i][1]/rhdiv => now;
                   // I still wasn't happy with it,
                   // but hey, "Publish or die." -- Rob Scott
                }
           }
           // this code is executed in non-glissando case
           else {
               // chucking a duration to now advances time
               // by that amount within the shred
               pulse*play[i][1] => now;
           }
       }
   }
   
   PlayScore( score, 0); // Calling the function once will play thru the melody once.
   // See if you can add multiple shreds of this at just the right time to play in round!
   // Try alternating lower and higher octaves!
   /*
   // remove lines 169 and 205, AND comment/remove line 165, to unlock...
   // CHAPTER TWO - Programmed Polyphony
   // a function to hang out between successive entries
   fun void waitLine() {
       (22.+2/3.)*pulse => now;
   }
   // to execute functions 'in series', simply call them, as 
   // to execute 'in parallel', use 'spork~' to create breakoff shreds.
   // 'spork a shred' > 'fork a thread', good one Ge Wang...
   
   // the below code initiates five separate shreds
   // to simulate five round entries
   
   spork~ PlayScore ( score, 0 ); // first entry
   waitLine();
   spork~ PlayScore ( score, 1 );
   waitLine();
   spork~ PlayScore ( score, 0 );
   waitLine();
   spork~ PlayScore ( score, 1 );
   waitLine();
   // now check this out
   // for the last entry, we gonna do a 'Meno Mosso' (slower tempo)
   // we change ONE VARIABLE, and all four lines follow!
   // if we had passed the pulse as an argument to each function instead of
   // using this sort of global variable, this wouldn't work.
   1.1 *=> pulse; // multiply value of pulse by 1.1 and re-assign
   spork~ PlayScore ( score, 0 ); // final entry
   // now, let the round play out;
   // if the main shred of this script terminated early,
   // it would automatically terminate any child shreds still running
   waitLine();
   waitLine();
   waitLine();
   waitLine();
   /*