Bjorklund: The Algorithm in C

October 18, 2014

Read it and weep. I know I am 😛

EDIT (2025): My code is long deprecated and has been greatly improved by Sergio Castro:

#!c++

std::string bjorklund(int beats, int steps)
{
    //We can only have as many beats as we have steps (0 <= beats <= steps)
    if (beats > steps)
        beats = steps;

    //Each iteration is a process of pairing strings X and Y and the remainder from the pairings
    //X will hold the "dominant" pair (the pair that there are more of)
    std::string x = "1";
    int x_amount = beats;

    std::string y = "0";
    int y_amount = steps - beats;

    do
    {
        //Placeholder variables
        int x_temp = x_amount;
        int y_temp = y_amount;
        std::string y_copy = y;

        //Check which is the dominant pair 
        if (x_temp >= y_temp)
        {
            //Set the new number of pairs for X and Y
            x_amount = y_temp;
            y_amount = x_temp - y_temp;

            //The previous dominant pair becomes the new non dominant pair
            y = x;
        }
        else
        {
            x_amount = x_temp;
            y_amount = y_temp - x_temp;
        }

        //Create the new dominant pair by combining the previous pairs
        x = x + y_copy;
    } while (x_amount > 1 && y_amount > 1);//iterate as long as the non dominant pair can be paired (if there is 1 Y left, all we can do is pair it with however many Xs are left, so we're done)

    //By this point, we have strings X and Y formed through a series of pairings of the initial strings "1" and "0"
    //X is the final dominant pair and Y is the second to last dominant pair
    std::string rhythm;
    for (int i = 1; i <= x_amount; i++)
        rhythm += x;
    for (int i = 1; i <= y_amount; i++)
        rhythm += y;
    return rhythm;
}

This was the most challenging piece of code to date. Outwardly simple, and with many existing examples in other languages, not to mention the C code example in Bjorklund’s paper, it should have been a doddle to implement on the Arduino, right?

But no. I realised the big downside to using the AVRISP: no access to the serial interface, which makes debugging impossible. Thankfully I could use the Teensy 3.1 to test my Code. But this in itself brought heartache, as there were some library conflicts with Teensyarduino. A troubling story to be sure, but In brief, I battled through ’til dawn and eventually cracked the bastard.

My overriding concern was – how much of the ATmega’s CPU time would be taken-up by using recursive function? I would have expected this to be a resource hog, and I worried that it wouldn’t handle 8 tracks simultaneously, slowing everything down. I’m happy with the current state of the MIDI clock (99.98% accurate), and this was something I didn’t want to compromise. I also witnessed some talk on the forums about Arduino’s limited stack size.

In the end, performance wildly exceeded my expectations. See the example outputs below.

Note that I have reversed the order or the patterns in alignment with the examples in Toussaint’s paper. See chapter 4 for many more examples. An interesting read for sure.

In the end, the pattern directions don’t matter, because I’ve implemented track rotation and track reverse in the main application. So…

For 8 steps and 3 pulses, the pattern is:
10010010

Bjorklund took 8.00 microseconds.

Cuban tresillo / Habanera rhythm. “It can often be heard in early rock-and-roll hits in the left-hand patterns of the piano, or played on the string bass or saxophone. A good example is the bass rhythm in Elvis Presley’s Hound Dog.

The tresillo pattern is also found widely in West African traditional music. For example, it is played on the atoke bell in the Sohu, an Ewe dance from Ghana. The tresillo can also be recognized as the first bar of the ubiquitous two-bar clave Son given by [x . . x . . x . . . x . x . . .].

For 8 steps and 5 pulses, the pattern is:
01101101

Bjorklund took 10.00 microseconds.

Cuban cinquillo. Used extensively in jazz, 50’s rockabilly and West African traditional music. e.g hand-clapping pattern ‘Hound Dog’.

For 12 steps and 4 pulses, the pattern is:
100100100100

Bjorklund took 10.00 microseconds.

The 12/8-time Fandango clapping pattern. (I know, I know)

For 3 steps and 2 pulses, the pattern is:
011

Bjorklund took 5.00 microseconds.

E(2,3) = [x . x] is a common Afro-Cuban drum pattern. For example, it is the conga rhythm of the (6/8)-time Swing Tumbao. It is also common in Latin American music, as for example in the Cueca.

Lastly, a silly example to check performance again:

For 83 steps and 56 pulses, the pattern is:
01110110110110110110110110110110110110110111011011011011011011011011011011011011011

Bjorklund took 63.00 microseconds.

IMG_4240

This is going to be damn sweet.
🙂

2 Responses to “Bjorklund: The Algorithm in C”

  1. nirulfen's avatar nirulfen Says:

    That is already quite sweet. Can’t wait to see where it goes!

    • stimresp's avatar stimresp Says:

      I got it working over the weekend and it’s :shock:.

      Can’t stop playing with it. It’s quite special. Will hvae a vid up by the weekend hopefully.


Leave a reply to stimresp Cancel reply