Update

On 19.07.01 there was a firmware update, now OP-Z can sample from usb or the mic making half of this article deprecated.

Intro

It began in the summer of 2018, when I’ve been playing with my PO-20 “Arcade” wondering if it’s hackable, maybe there’s a community around hacking pocket operators like there is one for Canon “Magic Lantern” firmware.

There is no such thing. But there is OTTO, an open source project initially inspired by OP-1 but clearly going in their own direction at the moment, consider contributing if you’re interested.

I was thinking about joining OTTO but ultimately decided against that, my main concerns were the power-hungry hardware (Raspberry Pi 3+) I wanted something smaller with long battery life.

The tools also raised some concern, everything was built from scratch in C++ and Faust, it would take years, and years it took to reach a V1.0 (still unreleased at the moment ofwriting) but no doubt the end result could be something beautiful.

Starting from scratch I was thinking to go the way of Critter and Guitari Organelle with Pure Data In a few days of toying around, I realized that visual programming will not cut it, I needed a proper programing language.

First prototypes

After a few days of comparing communities, language features and GitHub stars of some environments…

SuperCollider was looking like a winner. With an active open source community, it was like a silver bullet for all my problems, SuperCollider can easily be set up to run on a Raspberry Pi.

The choice of hardware at that moment was clear, a Raspberry Pi Zero and a dedicated audio board (Fe-Pi or Teensy audio adaptor both based on the same chip) would do the trick. Combined with a ~2000 mAh battery it should run for ~5 hours, still not as much as I would like but it will do for the moment.

Looks like a wannabe pocket operator, doesn't it?

The first prototype was quickly made in Fusion and the plastic parts printed. It, of course, has a few drawbacks:

  1. The buttons, I did not like the feel of the tall silicone buttons.
  2. Not enough buttons.

The second prototype used mechanical keyboard buttons, and it had a lot more of them. Initially, I cloned Volca Sample functional plus some extra stuff.

OP-1 anyone?

Then I started looking into how OP-Z handles the sequencing and started to recreate it in Supercollider. After some time took the plunge and bought an OP-Z, I think from the first or second publically available batches.

OP-Z Era

A tight fit

After spending some time with OP-Z I thought there is no point to try to recreate the sequencer, it would take too much time. I decided to reuse the Raspberry Pi and audio IO board and slapped them on the back of my OP-Z, it seemed the most reasonable way to get the most out of it in the shortest time possible, OP-Z already had the sequencer that I wanted but it didn’t have any sampling capabilities(at the time of writing) so it should be a beautiful fusion.

The end result

How to build something similar(dont’t)

Part list:

  1. Dedicated audio board with Line-In and Line-Out, Raspbian suports it out of the box.
  2. Raspberry Pi of your choice.
  3. A 5V power supply.

Steps to reproduce:

  1. Build Supercollider from source on Raspberry Pi
  2. Go to sleep, compilation is an overnight process on R-Pi Zero.
  3. Clone/download my repo.

It has two folders, opz-sc-extensions contains SuperCollider extension, for more details on how to use extensions with SuperCollider, the opz-plugin folder contains some files that launches the extensions and a golang-opz folder with some code needed to further process the SuperCollider sample output because the OP-Z won’t accept a simple .aif file.

Update

OP-Z recieved an update (1.1.27) and now you should be able to import WAV or AIFF files without a header (metadata).

It needs a custom “header”, this is needed only for the sampler. There was no particular reason for go, I just needed a tool that I could use to search and modify some bytes in the output file, there’s no such low-level API in sclang.

 
// Custom teenage enginnering .aif header for sample files
op-1{
    "adsr": [2624, 576, 26623, 6720, 4000, 64, 4000, 4000],
    "base_freq": 440,
    "fx_active": true,
    "fx_params": [8896, 14816, 1536, 6688, 8000, 8000, 8000, 8000],
    "fx_type": "spring",
    "knobs": [0, 28448, 32503, 32503, 12000, 0, 0, 9832],
    "lfo_active": false,
    "lfo_params": [2000, 26304, 5728, 14464, 0, 0, 0, 0],
    "lfo_type": "element",
    "name": "20140407_1233",
    "octave": 1,
    "synth_version": 1,
    "type": "sampler"
}

The custom header which is utf8 encoded and replaced the original “header” from SuperCollider output, thanks to Gero Takke for figuring things out.

To run the plugin on a device you’ll need to install golang then in the golang-opz directory run only once:

go build

 
// The code that replaces .aif headers.
    package main

    import (
        "bytes"
        "fmt"
        "io/ioutil"
    )

    func check(e error) {
        if e != nil {
            panic(e)
        }
    }

    func main() {
        headerData, err := ioutil.ReadFile("header")
        soundDonor, err2 := ioutil.ReadFile("input.aif")

        check(err)
        check(err2)

        ssndIndex := bytes.Index(soundDonor, []byte("SSND"))
        soundData := soundDonor[ssndIndex:len(soundDonor)]
        fullData := append(headerData, soundData...)

        ioutil.WriteFile("output.aif", fullData, 0644)
    }

Next you could open opz-sampler.scd or opz-synth.scd in SuperCollider or run headless:

export DISPLAY=:0.0 && sclang opz-synth.scd

There are quite a few pros and cons to this approach to an op-z plugin.

The pros:

  1. SuperCollider.
  2. An enormous library of UGens (units that process or generate sound) for SuperCollider.
  3. A community behind SuperCollider, usually you can find the answer to common questions but still, documentation is king.

The cons:

  1. Long boot times, around 1 min caused by a massive software stack.
  2. Latency, around 10 ms with just jackd process using 20% of the CPU.
  3. Additional latency because of SuperCollder’s client-server architecture.
  4. Unstable on Raspberry Pi, more software more bugs.
  5. jackd process would crash after one minute of inactivity if using a reverb effect for some reason.

In conclusion, the end product is not as practical as I wished it was, it boots slowly, massive software overhead, buggy and still power-hungry device, SuperCollider on Raspberry Pi Zero isn’t a good enough for this task.

The shape of things to come

I need a device with no boot time and almost real-time performance so I’ll go with a microcontroller, the Zero board is replaced with a Teensy 3.6, a small beast of a microcontroller with an additional chip of 8MB of RAM, and 32 GB of flash storage.

A propper plugin thingy

The follow-up…