Skip to content

Instantly share code, notes, and snippets.

@troelskn
Created January 14, 2023 22:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save troelskn/8408a25facc3878cf95dd1f31a8eea3b to your computer and use it in GitHub Desktop.
Save troelskn/8408a25facc3878cf95dd1f31a8eea3b to your computer and use it in GitHub Desktop.
Björklund's algorithm for calculating euclidean rhythms in pure C
#define ARRAY_TERMINATE 0
#define TRIGGER 'x'
#define REST '.'
// Will accomodate up to 64 long patterns
// If you want to handle larger sets, you probably need to rewrite this code
// to use dynamic arrays instead
int bjorklun_buffer[64][65];
int zarray_count(int arr[]) {
int counter = 0;
while (arr[counter] != ARRAY_TERMINATE) {
counter++;
}
return counter;
}
void zarray_concat(int target[], int source[]) {
int target_size = zarray_count(target);
int counter = 0;
while (source[counter] != ARRAY_TERMINATE) {
target[target_size + counter] = source[counter];
counter++;
}
target[target_size + counter] = ARRAY_TERMINATE;
}
// Usage:
// int pattern[14];
// bjorklund_calculate(13, 5, pattern);
// int length = zarray_count(pattern);
// for (int i=0; i < length; i++) {
// print((char)pattern[i]);
// }
void bjorklund_calculate(int length, int density, int output[]) {
if (density > length || density < 1) {
for (int i=0; i < length; i++) {
output[i] = REST;
}
output[length] = ARRAY_TERMINATE;
return;
}
// Init arrays
// Ex. l = 8 and d = 5
// [1] [1] [1] [1] [1] [0] [0] [0]
int width = length - 1;
for (int i=0; i < length; i++) {
bjorklun_buffer[i][0] = i < density ? TRIGGER : REST;
bjorklun_buffer[i][1] = ARRAY_TERMINATE;
}
int target, remainder_size;
while (true) {
if (width == 0) {
break;
}
if (bjorklun_buffer[width][0] == REST) {
// zero remainder
target = 0;
while (bjorklun_buffer[width][0] == REST && bjorklun_buffer[target][0] != REST) {
zarray_concat(bjorklun_buffer[target], bjorklun_buffer[width]);
target++;
width--;
}
} else {
// pattern-remainder?
remainder_size = zarray_count(bjorklun_buffer[width]);
if (remainder_size == zarray_count(bjorklun_buffer[0])) {
// no remainder present
break;
}
if (remainder_size != zarray_count(bjorklun_buffer[width-1])) {
// we have reached a core
break;
}
target = 0;
while (zarray_count(bjorklun_buffer[width]) == remainder_size && zarray_count(bjorklun_buffer[target]) != remainder_size) {
zarray_concat(bjorklun_buffer[target], bjorklun_buffer[width]);
target++;
width--;
}
}
}
// collapse rows into output
for (int i=0; i <= width; i++) {
zarray_concat(output, bjorklun_buffer[i]);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment