Skip to content

Instantly share code, notes, and snippets.

@unohee
Last active April 6, 2024 15:29
Show Gist options
  • Save unohee/d4f32b3222b42de84a5f to your computer and use it in GitHub Desktop.
Save unohee/d4f32b3222b42de84a5f to your computer and use it in GitHub Desktop.
Bjorklund Algorithm in C++
#include "Bjorklund.h"
//Edited NoisyLittleBurger's Bjorklund Algorithm in C
//http://www.noisylittlebugger.net/diy/bjorklund/Bjorklund_Working_Final/Bjorklund_algorithm_arduino.txt
//CHANGED :
//1. use dynamic array.
//2. fixed sequence's off-spot problem
//3. added Explanation about Algorithm based on G.Touissant's Paper,
//"The Euclidean Algorithm Generates Traditional Musical Rhythms"
//
//--------------------------------------------------------------
void Bjorklund::init(){
try{
iter();
}catch(out_of_range){
cerr<<"pulse::out_of_range"<<'\n';
}
}
void Bjorklund::init(int step, int pulse){
lengthOfSeq = step;
pulseAmt = pulse;
try{
iter();
}catch(out_of_range){
cerr<<"pulse::out_of_range"<<'\n';
}
}
void Bjorklund::iter(){
//\Bjorklund algorithm
//\do E[k,n]. k is number of one's in sequence, and n is the length of sequence.
int divisor = lengthOfSeq - pulseAmt; //initial amount of zero's
if(divisor < 0) throw out_of_range{"Divisor has to be greator than 0"};
remainder.push_back(pulseAmt);
//iteration
int index = 0; //we start algorithm from first index.
while(true){
count.push_back(std::floor(divisor / remainder[index]));
remainder.push_back(divisor % remainder[index]);
divisor = remainder.at(index);
index += 1; //move to next step.
if(remainder[index] <= 1){
break;
}
}
count.push_back(divisor);
buildSeq(index); //place one's and zero's
reverse(sequence.begin(), sequence.end());
//position correction. some of result of algorithm is one step rotated.
int zeroCount =0;
if(sequence.at(0) != 1){
do{
zeroCount ++;
}while(sequence.at(zeroCount) == 0);
std::rotate(sequence.begin(), sequence.begin() + zeroCount, sequence.end());
}
}
void Bjorklund::buildSeq(int slot){
//construct a binary sequence of n bits with k one’s, such that the k one’s are distributed as evenly as possible among the zero’s
if (slot == -1) {
sequence.push_back(0);
}
else if (slot == -2) {
sequence.push_back(1);
}else{
for (int i = 0; i < count[slot]; i++)
buildSeq(slot-1);
if (remainder[slot] !=0)
buildSeq(slot-2);
}
}
void Bjorklund::print(){
for(int i=0; i != sequence.size();i++){
cout<<sequence.at(i);
}
cout<<'\n';
cout<<"Size : "<<sequence.size()<<'\n';
}
vector<bool> Bjorklund::LoadSequence(){
vector<bool> seq;
for(int i=0;i < lengthOfSeq;i++){
seq.push_back(sequence[i]);
}
return seq;
}
#include <iostream>
#include <cmath>
#include <stdexcept>
#include <vector>
using namespace std;
class Bjorklund{
public:
Bjorklund(){};
Bjorklund(int step, int pulse): lengthOfSeq(step), pulseAmt(pulse){
if(lengthOfSeq <= 0 || lengthOfSeq < pulseAmt) lengthOfSeq = pulseAmt;
init();
};
~Bjorklund(){
remainder.clear();
count.clear();
sequence.clear();
};
vector<int>remainder;
vector<int>count;
vector<bool>sequence; //accessing sequence directly is discouraged. use LoadSequence()
int lengthOfSeq;
int pulseAmt;
void init();
void init(int step, int pulse);
void iter();
void buildSeq(int slot);
void clear();
void print();
vector<bool> LoadSequence();
int getSequence(int index) {return sequence.at(index);};
int size() {return (int)sequence.size();};
private:
};
@CtrlZ-Music
Copy link

Hey
thank you for sharing your code

I'm trying to compile it but I have this error :

main.cpp:52:45: error: ‘reverse’ was not declared in this scope
reverse(sequence.begin(), sequence.end());
^
main.cpp:60:9: error: ‘rotate’ is not a member of ‘std’
std::rotate(sequence.begin(), sequence.begin() + zeroCount, sequence.end());
^~~

@liamsmyt
Copy link

liamsmyt commented Apr 6, 2024

Hey thank you for sharing your code

I'm trying to compile it but I have this error :

main.cpp:52:45: error: ‘reverse’ was not declared in this scope reverse(sequence.begin(), sequence.end()); ^ main.cpp:60:9: error: ‘rotate’ is not a member of ‘std’ std::rotate(sequence.begin(), sequence.begin() + zeroCount, sequence.end()); ^~~

I also had this issue

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment