Created
January 14, 2023 22:41
-
-
Save troelskn/8408a25facc3878cf95dd1f31a8eea3b to your computer and use it in GitHub Desktop.
Björklund's algorithm for calculating euclidean rhythms in pure C
This file contains hidden or 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
#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