Basic git usage

Assuming you have already cloned a repository, the best place to start is with:

git status

This will show the current state of the files including the branch you are on and any untracked changes. If you’ve come back to a project after a few days off, this will remind you where you are (which branch) and what you were doing (un-committed changes and diffs).

‘git status’ may show modified files, such as:

On branch master
Your branch is ahead of 'origin/master' by 3 commits.
  (use "git push" to publish your local commits)

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

	modified:   ../../../src/apps/sequencer/engine/generators/RandomGenerator.cpp

no changes added to commit (use "git add" and/or "git commit -a")

To find out what is different in your changed files, type:

 git diff ../../../src/apps/sequencer/engine/generators/RandomGenerator.cpp

If your diff output is formatted incorrectly (escape codes instead of colors), try:

git config --global core.pager "less -R"

To show all branches:

git branch -a

To create a new branch:

git checkout -b <NEW BRANCH NAME>

To change to a new branch:

git checkout <branch name here>

To change back to the “default” branch :

check checkout master

To delete a branch:

git branch -d <branch_name>

To commit your changes

git commit -m "comment here"

Upload your changes to github

git push --set-upstream origin <your-branch-name-here>

The simplest way to create a pull-request and contribute code to open source projects on Github

Make a github account

Go to the project you want to contribute to

Press the “fork” button

Check out your forked copy of the project

git clone https://github.com/YOUR_USER_NAME_HERE/FORKED_PROJECT_NAME_HERE.git

Create a new branch and check it out (change “branch-name” to something descriptive of your work)

git checkout -b branch-name

Make your changes

Add each new or modified file to your commit :

git add path/to/file/file_name.c

Commit your change to your local branch

git commit -m "Add a comment about your changes here"

Sync your fork in case there have been any additions to the primary repository since you started your work

git remote add upstream https://github.com/original-owner-username/original-repository.git
git fetch upstream
git checkout master
git merge upstream/master

Push your changes to your forked repository on github

git push --set-upstream origin branch-name

Go to the page on github for your forked repository and press the “Compare & Pull Request” button. Follow the directions to create the pull request.

(adapted from https://www.digitalocean.com/community/tutorials/how-to-create-a-pull-request-on-github)

The Martyr as Proof of Religious Truth

It is often said that the truth of Christianity can be “proved” by the devotion of the many people who have died rather than deny Christ. The problem with this assertion is that willingness to die for a belief is no proof of the beliefs validity. There are surely many people who have died for causes of dubious truth.

What’s more, one could easily and truthfully argue that nearly anyone might be convinced to die for a cause given the right indoctrination. The many Christian Martyrs may be sincere but sincerity is not enough to make one correct.

I believe the actual strength of this argument in regards to Christianity may be the number of eye-witnesses who gave their lives. In particular the Apostles each have well documented (as much as something of near antiquity can be well documented – your requirements may vary from mine) martyrdoms.

Unlike a non-eyewitness, the eyewitness has real physical reasons to believe or disbelieve. We often place our emphasis on the Apostles belief. It may be better to think for a moment the possibility of unbelief. If Christ did not rise from the grave, the Apostles would have clearly known this. Perhaps they carried on and fabricated evidence in a desire to further their leaders work. This would have perhaps worked until faced with death for what you personally knew was a lie. It may even be possible that the rare, hyper-devoted person would die for this lie. However with Christianity we have multiple eye-witnesses giving their lives for “the lie”. The odds are much lower that this would happen.

Critics often remind Christians of the other “Messiah cults” of the time. I see these not as a stumbling block but further proof that false movements tend to die out because the eye witnesses are given reason to doubt and do exactly that. They doubt and give up. As noted, it might be possible for someone heavily invested in a lie to die for it but to have multiple people do so is not as likely. If the Christian “movement” was a lie, I believe the odds would be that most of the eye-witnesses would find a way to safely walk away when persecution flared up.

Christianity is unique in that multiple first-hand witnesses end up dying for their belief. One may argue that later Christians gave their lives after periods of prolonged exposure to Church propaganda. Later Christian martyrs believe because they were never presented with any physical evidence to the contrary of their belief. The same cannot be said of the Apostles. If Christ did not rise, they would have known it. This knowledge would make it very hard to die for something you personally know is not true.

Other faiths do not have a large number of “founding Martyrs”. Even among those that do, their strong faith is in that of an “ideal” – a belief in the truth of teachings. Early Christian martyr’s died in defense not of a ideal or beautifully stated holy work. Early Christian martyr’s died for refusing to deny a nearly absurd claim – the claim that Jesus Christ died and then rose back to life.

Given the right motivation a person could choose to die for all sorts of noble causes. The Christian Apostles died for a claim that they each would have had first hand knowledge of – did Christ rise from the dead? Many may be convinced to die for an ideal or indoctrinated belief. How many would die for a fact which they personally knew to be false? Perhaps pride or other circumstances would cause one or two to die for this false cause. However the number of founding martyrs in Christianity is high and diverse in time and place. I find it difficult to believe so many would die for something which they knew from first hand knowledge was absolutely untrue.

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.

Getting started developing for the Westlicht Performer

Here are my annotated notes on setting up OSX to contribute to the Westlicht performer sequencer.

1st step is cloning the github repository:

mkdir performer-sequencer
cd performer-sequencer
git clone --recursive https://github.com/westlicht/performer.git

I don’t recall if git is pre-installed on modern macs. If not you’ll need to install git as well. One item which is not installed is is cmake. Realizing I needed cmake and possibly other items is what prompted me to create this post.

I already had homebrew installed, so tried :

brew upgrade cmake
brew install sdl2
brew install libusb # perhaps not needed
brew install libusb-compat

which, after updating brew, worked (we’ll need sdl2 and libusb later on)

A first attempt at compiling is done with:

cd performer
make tools_install

Note that this step appears to install the arm compiler tools. I wish I would have skipped this and saw if things worked without them. Eventually I’ll need them but in case I do not move forward on this I’d prefer to not have the tools installed on my computer – especially as they are not under package management.

My install failed anyway with:

configure: error: libusb-1.x is required for the MPSSE mode of FTDI based devices
make[1]: *** No targets specified and no makefile found.  Stop.
make[1]: Nothing to be done for `install'.

so moving on…

make setup_stm32

sets up the build dirs according to the developers readme. Ran without fail.

Next up is:

make setup_sim

My first results i below. However as a note I performed a parallel install and had a different error:

libopencm3 submodule not found!

which was fixed with :

git submodule update --init --recursive

The first time I tried, it exited with:

-- Building for platform sim ...
CMake Error at /usr/local/Cellar/cmake/3.15.4/share/cmake/Modules/FindPackageHandleStandardArgs.cmake:137 (message):
  Could NOT find SDL2 (missing: SDL2_LIBRARY SDL2_INCLUDE_DIR)
Call Stack (most recent call first):
  /usr/local/Cellar/cmake/3.15.4/share/cmake/Modules/FindPackageHandleStandardArgs.cmake:378 (_FPHSA_FAILURE_MESSAGE)
  cmake/FindSDL2.cmake:173 (FIND_PACKAGE_HANDLE_STANDARD_ARGS)
  src/platform/sim/CMakeLists.txt:8 (find_package)


-- Configuring incomplete, errors occurred!
See also "/Users/jack/performer-sequencer/performer/build/sim/debug/CMakeFiles/CMakeOutput.log".
make: *** [setup_sim] Error 1

I need to fix this but first I may as well try compiling the sequencer itself:

cd build/stm32/release
make -j

which, surprisingly worked :

[100%] Built target sequencer

To build for the simulator:

make setup_sim
cd build/sim/debug
make -j

To run the simulator

./src/apps/sequencer/sequencer