Deeply diving into the Performer Generator Code

I don’t ask for much in life. “Just a bed and a Bible” as a man once said. But beyond the basics I do crave effective randomization for my sequencer. The Westlicht performer actually provides quite a bit in this regard. However within the many options, I found myself needing basic, quick randomization. The following is my journey to add that feature.

After getting a basic compile of the sequencer to work (see http://metajack.org/blog/2019/10/04/getting-started-developing-for-the-westlicht-performer/) I decided to work backwards. Update the UI and then fill the features in. This also will hopefully help me better find the code I need to modify.

I’m writing this after a brief session of digging and upon reflection I would recommend one at least goes through the directories to get a feel of the organization. Me? I dug right in with find and grep. It worked but I should have took a more civilized look at the code first.

I started with:

$ pwd
/Users/jack/performer-sequencer/performer/src
$ find . -type f -exec grep -q "Euclidean" {} \; -print
./apps/sequencer/CMakeLists.txt
./apps/sequencer/engine/generators/EuclideanGenerator.cpp
./apps/sequencer/engine/generators/EuclideanGenerator.h
./apps/sequencer/engine/generators/Generator.cpp
./apps/sequencer/engine/generators/Generator.h
./apps/sequencer/ui/pages/GeneratorPage.cpp
./apps/sequencer/ui/pages/GeneratorPage.h

At first it appears that each generator type has a class but inspecting Generator.h shows some code involving both types (or at least the selecting between them). Not sure if this is purposeful or not.

First though, let’s make a minor tweak and make sure things work as we expect. Let’s modify a bit of UI, compile and test:

$ find . -type f -exec grep -q "Seed" {} \; -print
./apps/sequencer/engine/generators/RandomGenerator.cpp
./apps/sequencer/engine/generators/RandomGenerator.h
./platform/sim/libs/args/catch.hpp
./platform/sim/libs/soloud/doc/sfxr.mmd
./platform/sim/libs/soloud/include/soloud_c.h
./platform/sim/libs/soloud/include/soloud_sfxr.h
./platform/sim/libs/soloud/src/audiosource/sfxr/soloud_sfxr.cpp
./platform/sim/libs/soloud/src/c_api/soloud_c.cpp
./platform/stm32/libs/libopencm3/include/libopencm3/stm32/common/rng_common_v1.h

I had hoped keeping “Seed” case-sensitive would lesson the matches. Inspecting RandomGenerator.cpp :

emacs ./apps/sequencer/engine/generators/RandomGenerator.cpp

yields up :

const char *RandomGenerator::paramName(int index) const {
    switch (Param(index)) {
    case Param::Seed:   return "Seed";
    case Param::Smooth: return "Smooth";
    case Param::Bias:   return "Bias";
    case Param::Scale:  return "Scale";
    case Param::Last:   break;
    }
    return nullptr;
}

We’ll change “Seed” to “Gene” then compile and run :

cd ../build/sim/debug
make -j
./src/apps/sequencer/sequencer

and indeed our change is there. Undo our change and set about how to add our own option…

Generator.cpp seems to be where we call our new custom Generator but how to add to the UI? Generator.h has the text for the modes. If we add a line for ours (let’s call our mode “Quick Random”) :

   static const char *modeName(Mode mode) {
	switch (mode) {
        case Mode::Euclidean:   return "Euclidean";
        case Mode::Random:      return "Random";
        case Mode::QuickRandom:      return "Quick Random";
        case Mode::Last:        break;
	}

and compile we’ll get an error – we’ve not defined QuickRandom. What if we copy and existing mode and rename it QuickRandom?

$ cp RandomGenerator.h QuickRandomGenerator.h
$ cp RandomGenerator.cpp QuickRandomGenerator.cpp

If we just rename the class, we’ll stick get an error when compiling. Need to check the errors and add a few more things in Generator.cpp

# add (keeping the string hash/pound symbol as it is a compiler directive
#include "QuickRandomGenerator.h"

# modify
static Container<EuclideanGenerator, RandomGenerator, QuickRandom> generatorContainer;

# add
case Mode::QuickRandom:
        return generatorContainer.create<QuickRandomGenerator>(builder);

and in Generator.h

public:
    enum class Mode {
        Euclidean,
        Random,
        QuickRandom,
        Last
    };

still not compiling …. did a few more things …

Finally add your files to cmakeList.txt so that the files you add are compiled and linked

After all this, got it working and we now have a new Generator menu item. For now our generator does the same thing as the one we copied. We’ll work on that next.

Leave a comment

Your email address will not be published.