Tutorials

Oopsy Daisy — An Introduction, Part 1

The new Daisypatch module from the folks at Electrosmith is here. It joins the Rebel Technologies OWL module - now reborn as the Befaco Lich, and provides another way to embed the precise flexibility of Max/MSP's gen~ into modular Eurorack hardware.

I've watched the project carefully since its Kickstarter days. Well, the wait is over — while the hardware and the Oopsy software environments are still a work in progress, I was keen to check it out. Thanks to the folks at Electrosmith (who kindly sent me some hardware to work with) and my friend and colleague Graham Wakefield (who put together the Oopsy package to streamline the mapping of gen~ to the Daisy hardware), I thought I'd walk you through setting up your working environment and showing you how Oopsy works.

The first part of this tutorial will include some information about how to get the software tools you’ll need to get started in place on your machine. At the end of this first part of the tutorial, you'll have everything installed and be able to upload the example files provided as part of the Oopsy software release.

In part 2, we're going to be taking a run at creating some different kinds of gen~ patches to download and run in the Daisypatch module.

Please note that even though I’m trying to keep this simple in the hopes of attracting and interesting those of you who might want to get started running gen~ patches in your Eurorack, I am making a few assumptions about what kind of system you’re working on. The reason for that is a practical one: I’m describing my current system — the one I loaded the Oopsy software on to create these patches. I hope they’re sufficiently basic that you can easily imagine how your own system may vary, and I hope that those of you on slightly different systems who do find changes or helpful tips will chime in in the replies.

It’s also the case that the Daisy software environment is a work in progress as of the time I am writing. There will definitely be bugs fixed as we go along. There will also be tweaks/new features added and in the works (you can find a list of those projects described here. Finally, it may well be that some of the basic installation and operation details for the Daisy software and the gen~ support for it may change over time, as well. It’s my plan to update and expand the contents of this tutorial when that happens so that the content remains as up-to-date as I can make it.

So let’s get stuff set up. First, I need to mention what the machine I’m starting the install on looks like:

  • I’m using a 2020 MacBook Pro running Catalina (10.15.7) with a beta version of Max (8.2.0) installed. I’ve checked around, and am informed that running the beta version of Max will exhibit no differences from running the most up-to-date version of Max currently available.

  • I’ve got a copy of Xcode installed on this machine (it’s version 12.4)

  • I use the SourceTree program to deal with GitHub repositories and various codebases.

I hope that none that is too exotic; I honestly don’t think so.

First Steps

My Daisy installation voyage started with the Installing the Toolchain on Mac page on the Daisy Wiki. According to the instructions, the first step is to install the command line utility software (gcc-arm-embedded dfu-util) used to flash the programs we’ll want to send to the Daisypatch module.

To do that, we use the open-source Homebrew package manager. The installation is remarkably straight-forward — navigate to the Homebrew package manager website and click on the clipboard icon to the right of the command line you’d be laboriously typing in to copy it to your clipboard.

Open a terminal window using the Macintosh Terminal program, paste the contents of the clipboard into the command line and hit return (you’ll be asked to enter your su password).

Here’s a shortened version of what you’ll see. The installer helpfully tells you what it’s going to do, what it’s downloading to install, and it’ll helpfully prompt you to make sure it’s what you want to do. When you’re all done, The installer exits and points you to more helpful information.

% /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
Password: <enter your password>
==> This script will install:
/usr/local/bin/brew
/usr/local/share/doc/homebrew
/usr/local/share/man/man1/brew.1
/usr/local/share/zsh/site-functions/_brew
/usr/local/etc/bash_completion.d/brew/usr/local/Homebrew
==> The following existing directories will be made writable by user only:
.
.
.
==> Installation successful!
==> Homebrew has enabled anonymous aggregate formulae and cask analytics.
Read the analytics documentation (and how to opt-out) here:
https://docs.brew.sh/Analytics
No analytics data has been sent yet (or will be during this `install` run).
==> Homebrew is run entirely by unpaid volunteers. Please consider donating:
https://github.com/Homebrew/brew#donations
==> Next steps:
- Run `brew help` to get started
- Further documentation:
https://docs.brew.sh
%

If you’re following along on one of the more security conscious Macs (i.e. if you’re running Catalina or Big Sur), you’re going to need to add an exception for security checks for gcc-arm-embedded stuff you’ve installed, just as you often have to do with third-party Max externals you’ve downloaded from someone else (If you’re following along on a Mojave machine, you don’t need to do this at all). Type these two lines into your Terminal and hit return

% find /usr/local/Caskroom/gcc-arm-embedded -type f -perm +111 -print | xargs spctl --add --label
% find /usr/local/Caskroom/gcc-arm-embedded | xargs xattr -d com.apple.quarantine

The second line listed in the toolchain page is intended to recursively remove the quarantine attribute in a directory. However, when I ran it, I got a huge collection of error messages of the basic form

% find /usr/local/Caskroom/gcc-arm-embedded | xargs xattr -d com.apple.quarantine
xattr: /usr/local/Caskroom/gcc-arm-embedded: No such xattr: com.apple.quarantine
xattr: /usr/local/Caskroom/gcc-arm-embedded/.metadata: No such xattr: com.apple.quarantine
xattr: /usr/local/Caskroom/gcc-arm-embedded/.metadata/config.json: No such xattr: com.apple.quarantine
xattr: /usr/local/Caskroom/gcc-arm-embedded/.metadata/10-2020-q4-major: No such xattr: com.apple.quarantine
.
.
.
xattr: /usr/local/Caskroom/gcc-arm-embedded/10-2020-q4-major/gcc-arm-none-eabi-10-2020-q4-major/share/gcc-arm-none-eabi/samples/src/fpin/fpin.c: No such xattr: com.apple.quarantine
xattr: /usr/local/Caskroom/gcc-arm-embedded/10-2020-q4-major/gcc-arm-none-eabi-10-2020-qmajor/share/gcc-arm-none-eabi/samples/src/makefile.conf: No such xattr: com.apple.quarantine
%

(and I do mean a huge collection of error messages).

As nearly as I can tell, there’s nothing that requires running this command on the contents of that file at all. However, I also realize that perhaps Big Sur operates with a slightly different set of rules and requirements, so perhaps this is necessarily there but not on Catalina installations. I think that that second instruction in the toolchain document is either not needed on Catalina installations, or its inclusion is generally not required.

Grabbing Some GitHub

So I’ve successfully installed the software to handle flashing the code to the Daisy Seed module, and it’s time to move on to creating a repository of Graham Wakefield’s Oopsy development software and compiling the Daisy library locally. I know that there are a lot of folks out there who love running GitHub from the command line, but I am personally more partial to the SourceTree application for this kind of thing.

To set up your local repository using SourceTree, you’ll need three things:

  • The URL of the github repository you want to clone

  • A destination on your local machine where you want to stash the files — I decided to put my stuff in with my installed Max Packages folder. Your mileage may vary.

  • A simple and short name that SourceTree will use to label your repository (How about… well… Oopsy?)

    So I launched SourceTree and set up my local repository by click on the “+ New Repository” menu and choosing Clone from URL to bring up the “Clone a repository” dialog box.

After that, I just input my source URL, the pathname for my install, and oopsy for the repository name and let SourceTree do the rest.

SourceTree went off and grabbed the entire repository and stashed it on my system.

Compiling the Daisy Library

After that, there was just one more step for setup: Compiling the Daisy Library itself on my machine.

To do that, I fired up my Terminal application one more time, opening the directory my Oopsy files lived

% cd /Users/gtaylor/Documents/Max\ 8/Packages/oopsy

(Remember that pesky space in the “Max 8” directory? You’ll need to use a backslash to preface the blank space when you type it in. You’re welcome.)

After that, the command ./install.sh will run the shell command that builds everything for you

% ./install.sh
/Users/gtaylor/Documents/Max 8/Packages/oopsy
get submodules
rebuilding everything. . .
only errors, and warnings will output. . .
-------------------
rebuilding libdaisy
In function 'gen_numname',
inlined from 'dir_register' at Middlewares/Third_Party/FatFs/src/ff.c:2339::
Middlewares/Third_Party/FatFs/src/ff.c:1825:8: warning: writing 1 byte into a region of size 0 [-Wstringop
overflow=]
1825 | ns[i] = '~';
| ~~~~~~^~~~~
Middlewares/Third_Party/FatFs/src/ff.c: In function 'dir_register':
Middlewares/Third_Party/FatFs/src/ff.c:1796:7: note: at offset -1 to object 'ns' with size 8 declared herec
1796 | BYTE ns[8], c;
| ^~
arm-none-eabi-ar: creating build/libdaisy.a
done building libdaisy
%

If you’re like me, you used the ls -la command to check on the contents of the top level of the Oopsy file system. If you do, you’ll probably notice that it looks as though nothing’s changed as a result of doing the install. Don’t worry - the results of your compiling labor have been safely stashed in the source directory. You can cd to that directory to make sure that everything worked (I use the ls -lt command because it lists the most recently changed files first).

% cd source
% ls -lt
total 208
drwxr-xr-x 31 gtaylor staff 992 Feb 13 23:20 libdaisy
drwxr-xr-x 5 gtaylor staff 160 Feb 11 12:40 build_frippery_patch
drwxr-xr-x 5 gtaylor staff 160 Feb 11 11:15 build_LFO_1_patch
drwxr-xr-x 5 gtaylor staff 160 Feb 11 08:21 build_LFO_4_frippery_patch
drwxr-xr-x 5 gtaylor staff 160 Feb 11 08:07 build_LFO_4_patch
drwxr-xr-x 5 gtaylor staff 160 Feb 11 08:05 build_simple_patch
drwxr-xr-x 5 gtaylor staff 160 Feb 10 22:33 build_LFO_1_LFO_4_patch
drwxr-xr-x 5 gtaylor staff 160 Feb 10 11:59 build_modfm_patch
drwxr-xr-x 5 gtaylor staff 160 Feb 10 10:14 build_midside_patch
-rwxr-xr-x 1 gtaylor staff 355 Feb 9 17:32 test.sh
-rw-r--r-- 1 gtaylor staff 2493 Feb 9 17:32 readme.md
-rwxr-xr-x 1 gtaylor staff 24775 Feb 9 17:32 oopsy.js
-rw-r--r-- 1 gtaylor staff 27326 Feb 9 17:32 genlib_daisy.h
-rw-r--r-- 1 gtaylor staff 9111 Feb 9 17:32 genlib_daisy.cpp
drwxr-xr-x 5 gtaylor staff 160 Feb 9 17:32 gen_dsp
-rw-r--r-- 1 gtaylor staff 1938 Feb 9 17:32 daisy.versio.json
-rw-r--r-- 1 gtaylor staff 1431 Feb 9 17:32 daisy.pod.json
-rw-r--r-- 1 gtaylor staff 2679 Feb 9 17:32 daisy.petal.json
-rw-r--r-- 1 gtaylor staff 2284 Feb 9 17:32 daisy.patch.json
-rw-r--r-- 1 gtaylor staff 4506 Feb 9 17:32 daisy.field.json
-rw-r--r-- 1 gtaylor staff 907 Feb 9 17:32 changelog.md
%

That’s it. In fact, that’s really all of the hard stuff. Now - onward to fun!

Oopsy-Daisy

Now that I had my software set up and configured, I thought I’d start by trying something simple — trying to compile and load the simple.maxpat file from the examples folder in my repository.

To do that, I needed to grab the handy cable that came with the Daisypatch and hook it up — one end into the little connector on the bottom of the Daisy Seed, and the other to my USB connection on the laptop (through a dongle, because Apple).

Opening the simple.maxpat patch showed me the appealingly minimal beginnings of my Daisy life… a single gen~ object, and a bpatcher with some controls and a display.

I figured I’d start by double-clicking the gen~ object to see what was inside:gen~ object to see what was inside:

Nothing too threatening here: some noisemaking stuff (noise and cycle operators), two pairs of param operators whose names seemed suspiciously as though they might relate to the controls and inputs/outputs of my Daisypatch, and a little patching to modify amplitude.

A little investigation into the controls on the bpatcher that handles the compilation and downloading looked equally straight-ahead.

To my surprise, the display in the bpatcher starting outputting messages when I opened the patch:

So it looks like the Oopsy stuff compiles whatever’s in the gen~ object automatically, although nothing had really changed about the behavior of my Daisypatch. So - despite what I was seeing in the little window - the flashing to the Daisy Seed wasn’t working.

Okay. What else is there besides the big button and the display? There are a couple of umenu objects that let me set what kind of Daisy device I wanted to flash programs to, and one that lets me set the sample rate for what I’m flashing (Wait - I can run stuff at 96 kHz? Wow. I’ll have to look into that later on….). Finally, there’s a helpful button that lets me toggle between “discreet” and “verbose” modes.

I figured that I could set the bpatcher to verbose mode to see if there was more information about what was working (or not working, in my case). So I set it to verbose and punched the button.

The results were helpful in terms of telling me what was going on. At the bottom, it looked like I had two problems: errors from the dfu-util stuff I’d just installed, and a message that said that the flash failed.

Note: I have since learned that I can ignore the DFU error messages, and so should you.

Since I’m excited about the Daisypatch and want you to have a good experience working with it and creating and flashing your own gen~ patches, dear readers, I am willing to appear as ignorant as I truly am: There was something really simple I hadn’t read far enough ahead to figure out. In order to be able to flash stuff to the Daisy Seed, I needed to put the Daisy into flashable mode first so that the module was ready to expect what I was sending to it.

I should have had a good idea of the problem. It’s described right here in the Oopsy help file. See that bit about “If the device is plugged in via USB and ready to flash….”

I know. “Duh.” But it wasn’t immediately obvious to me (perhaps this will change at some future point, but it’s how things are at the time of this writing). So I can save you some time here: Take a close look at your Daisy seed.

See those two little microswitches labeled BOOT and RESET? Good. To set your Daisy up to receive your compiled gen~ patch, hold down the BOOT button and then press the RESET button. Once you release the RESET button, you can let go of the BOOT button (you can tell you did it right if the USER LED on your Daisy Seed stops flashing.

Having pushed those two buttons and set my Daisy to receive stuff flashed to it, I punched the “go” button in the bpatcher again. This time, my verbose output had good news for me.While I still saw the error messages for the DFU utility, that bottom line said done…

...and - more to the point - my Daisypatch looked just a little different. Something happened!

Plugging patch cables into the first two audio outputs and listening to my mixer confirmed that I’d successfully downloaded the simple patch. Woohoo!

Now you should be all set to investigate some of the features of the Oopsy gen~ patching world in more detail. We'll be digging into that in the next part of this tutorial, but you'll find a couple of example patches in the examples folder of your Oopsy repository. Try 'em out, and I'll see you next time!

Learn More: See all the articles in this series

by Gregory Taylor on February 16, 2021

Jean-Francois Charles's icon

It's wonderful to see this tutorial here!

Francisco Colasanto's icon

Well done Gregory !!

Ryan Palm's icon

I love this device. I've been implementing things I've always wanted in eurorack with it. And I can change what it does day by day. Amazing.

mirko.ferremi's icon

Hi, thanks for the helpful tutorial.
I've just received my Daisy Patch module and can't wait to make it work.
I followed your guide step by step but for me the procedure stops at the "./install.sh" point.
As I type that command, I receive back this:

zsh: no such file or directory: ./install.sh

Can you tell me what I'm doing wrong? I'm not used to terminal commands.

Thanks.

Gregory Taylor's icon

Have you used the cd (change directory) to move into the home directory of the repository you downloaded? You can tell where you are in the terminal by using the pwd (print working directory) command.

guess I should add something about that.... <rummage rummage>

It's there already! Okay - here's what you need to check on. From the original above:

To do that, I fired up my Terminal application one more time, opening the directory my Oopsy files lived

% cd /Users/gtaylor/Documents/Max\ 8/Packages/oopsy

What you type after the cd (change directory) command in the Terminal application will depend on where you've installed your repository (that is, the location you typed into SourceTree as the Destination Path). the install.sh file is in the oopsy directory, and you need to be there to have typing ./install.sh on the command line to work. I believe that what your error message is telling you is that you're not currently in the right directory. Check to see if the response to typing in "pwd" agrees with that you entered as the Destination Path when you set up your repository.

I hope this helps.

Fiocz's icon

More !! More !!

mirko.ferremi's icon

Than you for your reply, I checked once again and yes, I used the cd command in the proper way, I'm in the oopsy directory but the install shell doesn't work.
It goes on saying:

"zsh: no such file or directory: ./install.sh"

Maybe I did something wrong with source tree and it didn't download all the necessary files in the Max 8/Packages/oopsy directory?

Could someone maybe upload or send me via email or wetransfer the "oopsy" directory so I can just do a copy/paste and then it should work?

Thanks,

Mirko

Rob Ramirez's icon

you can download a zip directly from the github repo : https://github.com/electro-smith/oopsy/archive/main.zip

mirko.ferremi's icon

OOOK now it worked! Thanks.
By the way, the oopsy main directory that I downloaded as a zip has a slightly different file content than the oopsy directory that I imported via Sourcetree. Strange.
Anyway I haven't got the Daisy Patch with me now, I'll try in a few days as soon as I get back home.
But thank you very much anyway.

missmiss's icon

I've been stuck on the first of the fist step, the installation of homebrew... ...

Can anyone tell me what happened?

Graham Wakefield's icon
Daniele Fabris's icon

Thanks Gregory for the great and useful tutorial !

Hannes d'Hoine's icon

I don't know if this is the right place for it, but I've ran into an issue on my Daisy Patch. The patch stops working after a couple of minutes. I don't know of this has to do with the code or with Oopsy or the module itself. I've opened a ticket on github...

Graham Wakefield's icon

I don't see anything unusual with the patcher that could cause this.

Except that I see you have [in 5 midi] -> [out 8 midi] repeated twice in the patch -- I'm not sure if this would be an issue or not, but it would be easy to delete this and confirm whether it fixes the freeze up.

Typical causes of a freeze up are:

  • A sudden spike in audio processing -- with gen~ this can only happen if you have a codebox with a for loop of unpredictable size, but there's none in your patch so it can't be this.

  • A memory leak. The gen~ exported code has absolutely no runtime memory allocations, and I'm pretty sure that the Oopsy-generated code doesn't either, so they can't be causing memory leaks. I doubt libdaisy MIDI handling would be an issue either but it might be worth looking into.

  • Illegal data in an input data stream -- which in this case could only be MIDI handling.

A couple of things you could test (and update the ticket on github with your findings) is:

  • If you don't connect any MIDI at all to the Daisy Patch, does it still freeze up? (If not the problem is MIDI handling -- perhaps there's something odd about the MIDI generated by the 16n faderbank, and it could be worth testing with another MIDI controller).

  • If it does still freeze up with no MIDI device connected, then does the time it takes from startup to freeze-up consistent? If so it points to a memory leak.

Another really useful thing you could do is to gradually strip out parts of the patch until the problem resolves, and that way it would narrow the problem down.

Hannes d'Hoine's icon

thanks for the quick reply. It must be a memory leak then. I deleted the double midi in and outs, (after three attempts I even deleted both [in 5 midi] -> [out 8 midi] objects), disconnected the midi controller, and it keeps occurring, every time after 5:50 minutes (hard to tell if it is exactly the same length, but I suppose it is). I will try stripping the patch and update the ticket when I found the issue. Thanks again.

Hannes d'Hoine's icon

Yes!! I found it. Thank you for pointing me in the direction of a leak. I have no experience whatsoever coding, but when I noticed that the lockup occurred about 2 times faster when I doubled the samplerate, I assumed there was something wrong with a counter somewhere. The main clock was a [=+1] object, and apparently Daisy can count only until a certain number and then it starts acting weird. I replaced it with a counter that resets after 10*samplerate. It's running for 45 minutes straight now so I think I'm good. Thank you very much! (I will add the explanation to the ticket as well.)