jane doe
..
eine neue datei euclid.bsh im verzeichnis commands anlegen und folgenden inhalt einfügen.
das ergebnis ist im sequencer eine belegung der steps nach dem euklidischen algorithmus.
quellen:
das ergebnis ist im sequencer eine belegung der steps nach dem euklidischen algorithmus.
quellen:
- http://www.quotile-sequencer.com/
- http://cgm.cs.mcgill.ca/~godfried/publications/banff.pdf
- http://ruinwesen.com/blog?id=216
Code:
/*
* euclid.bsh
*
* copyright by nina scholz, 2009
* feel free to e-mail me at nina [at] the-abc.de
*
* for quotile, found at http://www.quotile-sequencer.com/
*
* sources:
* http://cgm.cs.mcgill.ca/~godfried/publications/banff.pdf
* http://ruinwesen.com/blog?id=216
*
* comment: i dislike the string solutions (as in the sources described), so i changed it to a more algorithmic way.
*
*/
signature = "pattern,row,int,int";
documentation = "Generates the euclidean rhythm for a row based on 16 steps. (Nina Scholz)";
syntax = "euclid [pattern-name] [row: 1 - 16] [amount: 1 - 127] [pulses: 1 - 16]";
example = "euclid p6 2 127 13";
run() {
euclid(int pulses, int steps) {
int [] sequence = new int[pulses];
int seqCount = 0;
int repeats = ggt(pulses, steps);
pulses /= repeats;
steps /= repeats;
int remainder = steps % pulses;
int interval = (steps - remainder) / pulses;
if (remainder <= 1) {
while (seqCount < pulses - 1) {
sequence[seqCount] = interval;
seqCount++;
}
sequence[seqCount] = interval + remainder;
seqCount++;
} else {
int aMax = remainder;
int bMax = pulses - remainder;
int maxGGT = ggt(aMax, bMax);
aMax /= maxGGT;
bMax /= maxGGT;
int bFill = 0;
int addLast = 0;
if (aMax > bMax && aMax % bMax == 1) {
addLast = 1;
aMax--;
maxGGT = ggt(aMax, bMax);
aMax /= maxGGT;
bMax /= maxGGT;
}
if (bMax > aMax) {
bFill = bMax % aMax;
bMax = (bMax - bFill) / aMax;
if (bFill > 1) bMax++;
aMax = 1;
}
boolean isACount = true;
int count = aMax - 1;
while (seqCount + addLast < pulses - bFill) {
if (isACount) {
if (count < aMax) {
sequence[seqCount] = interval + 1;
count++;
} else {
sequence[seqCount] = interval;
count = 1;
isACount = false;
}
} else {
if (count < bMax) {
sequence[seqCount] = interval;
count++;
} else {
sequence[seqCount] = interval + 1;
count = 1;
isACount = true;
}
}
seqCount++;
}
while (seqCount + addLast < pulses) {
sequence[seqCount] = interval;
seqCount++;
}
}
if (addLast == 1) {
sequence[seqCount] = interval + 1;
seqCount++;
}
if (repeats > 1) {
for (int i = 1; i < repeats; i++) {
for (int j = 0; j < seqCount; j++) {
sequence[i * seqCount + j] = sequence[j];
}
}
}
return sequence;
}
int ggt(int a1, int a2) {
if (a1 < a2)
return ggt(a2, a1);
else if (a2 != 0 && a1 % a2 != 0)
return ggt(a1 % a2, a2);
else
return a2;
}
pattern = arg1;
row = arg2 - 1;
amount = arg3;
pulses = arg4;
int [] sequence = euclid(pulses, 16);
int seqOffset = 0;
pattern.clear();
for (int i = 0; i < pulses; i++) {
pattern.set(seqOffset, row, amount);
pattern.set(seqOffset + 16, row, amount);
seqOffset += sequence[i];
}
pattern.draw();
}