Content You Need: Getting to Know the OWL Pedal, Part 2
As promised, here’s part 2 of my article about the OWL audio processor. There’s been a significant development since we published part 1 - the arrival of the new OWL package available now from the package manager in Max 7.
Tom’s video shows is a walkthrough of the workflow with the new OWL package:
Collaboration
Over the last year, we have been working closely with the OWL guys at Rebel Technology, and this package is the result of that effort. It is now possible to work completely inside of Max to program and set up your OWL . We still use the Rebel Technology server back end to do the compiling and heavy lifting of the gen~ code, but there’s no more uploading files to the website and moving to the browser to complete the transfer.
The end result is a seamless workflow from inside of Max directly to the hardware, which also allows for saving of the code up in your account on rebeltech.org. Nice, huh?
Inside the Package
From the launcher patcher, found in the extras menu in Max after you install the package, you can fire up the OWLwatcher patcher.
The OWLwatcher patcher does all the work of getting your gen code to the OWL, and you need to have it open for this all to work. The OWLwatcher grabs exported gen code and uploads it to rebeltech servers, where it is compiled down to OWL friendly byte code and sent back to your instance of Max. From there we bundle it up as sysex and send it out to your OWL device over a MIDI port.
Piece of cake! There are some cracking examples in the package, coded by the rebeltech guys. You can use these as is or as a starting point for your own creations.
In Action
Over the course of my several weeks working with the OWL pedal, I have come to appreciate it in a zen-like way. Like a lot of Max programmers, I tend to suffer from a serious case of the feature bloat disease.
“If I just add another do-hicky to it, it will be that much more cool”
You can’t do this with the OWL. You can’t load up an entire performance rig of code, and whatever you do load up, it needs to work with 4 dials, a pedal and a button. As someone who needs to use both hands to play an instrument, it needs to work with a pedal alone. So I have come to enjoy the process of creating little one shot patchers. Stuff like custom ring mods, distortions, smeary delays - in all cases, I load it up to do one simple thing well. This has led me to a real appreciation of the form factor. If you’re looking for a rig replacement, this isn’t it. But it plays super nicely as a customisable part of a larger set up. Reliability has been superb. My pedal still feels super solid under foot.
Looking ahead
We’re really pleased to be a part of this release, and we wish the Rebel Technology team the very best. I’m looking forward to working on more developments for this package, and with them as they grow their product line.
In particular, this release has a sense of breaking new ground for me. It represents Cycling ‘74 acting as a publisher of an “eco system”. This is a coding environment, content and a web based delivery mechanism all rolled into one package. That’s an interesting step for Max - I wonder where it might lead?
First of all I want to say that it is great to see Cycling and Owl collaborating like this. Like @Arabrab I am keen to see more.
Secondly, I want to ask/suggest/complain...
Two small things:
- The new [owl.hasher] external is great. It would be even better if it was open source and the code included in the package 'source' folder.
- The OWLwatcher patch is great, but a complete mess inside and I had to painstakingly pick it apart to work out what is going on.
More disappointing:
- There is no indication or advice anywhere in this package about CPU usage requirements and restrictions before the act of actually compiling - how am I to get an understanding of what can be done if I do not have feedback on what the pedal (or EuroRack) itself is capable of whilst writing in Gen, rather than just after sending to the server? And not just statistics, but specifically hints on what might be prohibitively expensive in the compiled Gen code when reaching the pedal. Etc.
- There is no indication or advice anywhere in this package about MEMORY usage restrictions before the act of actually compiling and sending to server. I really need to know these things up front before committing. What can I reasonably expect to do with Data & Delay operators? Etc.
- There is no advice on GenExpr with regards OWL. I.E., does the GenExpr way of just declaring param operators inside the body of code work correctly? I presume it does, but I cannot be sure based on this package, as there are no examples and no mention of it.
- How is if/else branching and dynamic CPU management? How is function management?
- There is no discussion of polyglotDSP in this package. What happens in the translation process? Are there any 'gotchas' for specific Gen operators when compiling to OWL?
I would expect all of these issues and more to be addressed in a dedicated package. At the moment it is threadbare.
- the owl.hasher object produces a nonce and hash for the Rebel Technology server for a generic Max user (their server uses an authentication mechanism to ensure that only real users can use the compiler). Since the API key is slightly sensitive, we build a C external around it. There's nothing interesting in the source code -- it uses c++11 random distributions and a sha256 algorithm to prepare the data for the server. I'm not sure what you think you can do with it beyond the one thing it's doing right now. By the way: if you put an 'owl-key.txt' containing your personal API key in your Max search path, owl.hasher will use that key instead of the generic one. That way, your patchers will be properly associated with your account on the Rebel server.
- the mess inside of OWLwatcher is 100% my fault, mostly since I never expected that anyone would care how it works -- most of the logic is in JS anyway. If someone wants to clean it up, great! Or I'll do it myself on a rainy day. Sorry about that.
- as for CPU and memory restrictions, we could considering adding more verbose communication with the server/device when things go wrong. Some of that threadbareness is due to the minimalistic nature of the API we're using, but C74/Rebel could do more work there. Thanks for the feedback.
- as for Gen features: the same source code is being exported which you would use for a VST plugin or any other application with Gen. We have made some executive decisions to always use the 'fast' version of certain operators (tan, tanh, exp, log, log2, pow, pow2) and ARM/CMSIS versions of others (sin, cos, sqrt) to better support the hardware limitations. You're right, though, that this deserves documentation. We'll endeavor to fix that up in an update.
- if you want to better understand the architecture of the ARM Cortex M4 (STM32F4) (the MCU of the OWL), I would recommend taking a look at The Definitive Guide to ARM Cortex-M3 and Cortex-M4 Processors by Joseph Yiu. It's an astonishingly capable processor for its price, size and power consumption. But it does have limitations running general-purpose code which hasn't been hand-optimized for the platform. The OWL platform has added some additional heap memory to the out-of-the-box STM32F4 spec, but 1MB won't get you very far with 48kHz/24-bit audio quality if you want to create delay lines, etc. Anyway, I digress... newer versions of the Cortex M processor support larger, faster SRAM, so maybe we'll see improvements there in the future.
@STKR glad you like our work. It's still early days, but we're really excited about it.
The OWL hardware can process 3500 floating point operations per sample running at 48kHz / 24bit and has a bit more than 1 Mbyte memory available for tables and buffers.
Exactly what that means in terms of how much you can fit into a Gen patch is almost impossible to say beforehand, as the Gen code is compiled into highly optimised machine code. Once loaded, you will get an instant readout of the CPU and memory load on the device from the OWL Watcher.
In practice the way you develop a patch is to start with moderate to small tables, see how much they consume, then scale up.
To get an idea of what the OWL capabilities are I'd encourage you to have a look at our patch library [1], which is full of examples and contains (switches tab)... currently 175 published patches. Most of these are not Max Gen, but they still give you an idea of what you can do with an OWL. And remember that you can try the patches out in the browser!
Gen is the most recently added language that OWL supports, and our collection of examples is growing. Currently there are 20 public Gen patches, the most recent a port of Akihiko Matsumoto's Foreverb. And it's awesome!
Thanks. All that is very useful info and I appreciate it. All of it should be explicitly documented in your package.
@Jeremy, sure, I understand about [owl.hasher] and the patch. I just like to know more in case I want to roll my own at any stage.
"We have made some executive decisions to always use the 'fast' version of certain operators (tan, tanh, exp, log, log2, pow, pow2) and ARM/CMSIS versions of others (sin, cos, sqrt) to better support the hardware limitations."
^^ OK, so, this is huge, and that is exactly what we need to know. And we need more detailed comparisons of these operators. These decisions have a massive effect on accuracy of pitch and time calculations for example, or the sound qualities of a custom oscillator, etc. Info like this should be in the package. It is sort of insane that this is not documented. Basically you are saying that what we get on the Owl is not what we hear when building our Gen patch. That is ok, but we should be explained this up front.
The problem for me is the memory. Not enough. I will wait for the technology to progress for what I want to do, but in the mean time I will have a play.