One for All: Difference between revisions
Created page with "Rough multitrack recording by Jacob Barton, http://oneforall.ytmnd.com" |
m Categorised this uncategorised page |
||
(5 intermediate revisions by one other user not shown) | |||
Line 1: | Line 1: | ||
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 [http://chuck.cs.princeton.edu the ChucK environment] (copy and save the below text as a .ck file to use in ChucK): | |||
<nowiki>/* 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(); | |||
/*</nowiki> | |||
[[Category:Composition]] | |||
[[Category:Sagittal notation]] | |||
[[Category:Scores]] | |||
[[Category:Listen]] |