Created
January 29, 2019 10:54
-
-
Save chadochan/b42fb823ebb866b4126a0c604ea55121 to your computer and use it in GitHub Desktop.
EdgeList class takes two rhythm arrays (each comprised of 0 and 1 values) and makes a composite array.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
EdgeList takes two rhythm arrays and makes a composite array, returning a 3D array with the unit duration, the composite array, | |
and the IOI times between events in the composite (in seconds). Can be used as an edge list for a graph. | |
The array arguments should be comprised of 0 and 1 values, and must each contain at least one value. | |
*/ | |
EdgeList { | |
var array1, array2, object; | |
*new { |array1, array2, object = 1| // possible to pass in any object, but just use 1 if you want a normal rhythmic array.. | |
var composite_array, composite_size, ioiarray_ints, ioiarray_times, lastelement; | |
var unit_duration; | |
var divisor; | |
if(array1.size < 1 or: { array2.size < 1 }, | |
{ "Both arrays must hold at least one value".warn; | |
^this; | |
} | |
); | |
/* | |
calculate the correct size for the composite_array: | |
as the given arrays may have multiple periods, i.e., 3 'bars' of 5, as in Nbit(5, 3), | |
use gcd to find the number of common periods. Thus, the base unit duration returned below will | |
be the base unit for 0/1 to 1/1, regardless of the number of periods in the constituent Nbit arrays.. | |
*/ | |
divisor = gcd(array1.size, array2.size); | |
composite_size = (array1.size*array2.size)/divisor; | |
// create new list of the required size to hold the composite; fill it with zeros: | |
composite_array = List.fill(composite_size, {0}); | |
// add the elements from the given arrays to their correct positions in the new composite array: | |
array1.do { |item, i| | |
if (item == 1) { composite_array[i*((array2.size)/divisor)] = object }; | |
}; | |
array2.do { |item, i| | |
if (item == 1) { composite_array[i*((array1.size)/divisor)] = object }; | |
}; | |
/* | |
calculate the base unit duration for the graph, again using the divisor | |
to take into account multiple beat lengths in the given Nbit arrays | |
(Nbits must have the same number of beats for this to be accurate) | |
*/ | |
unit_duration = (1 / (composite_array.size/divisor)).round(0.000001); | |
postln("*****************"); | |
postln("Minimum base unit duration for this graph is: " ++ unit_duration); | |
/* | |
find the addresses containing 1, then find the 'wraparound' interval | |
between the last value and the first | |
*/ | |
ioiarray_ints = composite_array.indicesOfEqual(object); | |
lastelement = (ioiarray_ints.first - ioiarray_ints.last)%(composite_array.size); | |
// calcuate differences between values in adjacent addresses, i.e., the distances between '1' slots | |
ioiarray_ints = ioiarray_ints.differentiate; | |
/* | |
add the 'wraparound' interval to the end of ioiarray and replace the first element with the offset | |
(if 0, then the first address is a '1') | |
*/ | |
ioiarray_ints.remove(ioiarray_ints[0]); | |
ioiarray_ints.add(lastelement); | |
postln("Node IOI integers: " ++ ioiarray_ints); | |
// scale integer IOIs by the unit_duration, print result | |
ioiarray_times = ioiarray_ints.collect({ |item, i| (item * unit_duration).round(0.000001) }); | |
postln("Node IOIs: " ++ ioiarray_times); | |
/* | |
add a tailing 0 to serve as a final 'ghost node' with | |
a duration of 0, allowing antipenultimate nodes or earlier to connect through to the end of the graph period | |
*/ | |
ioiarray_times.add(0); | |
^[unit_duration, ioiarray_times, composite_array] | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment