Anatomy of a Reaktor Project, Part I
In a previous tutorial, Programming and Design in Reaktor, I covered several concepts pertaining to the creation of large and complex Reaktor structures. Out of necessity, the paper deals mainly with generalizations, as each Reaktor ensemble will bring it’s own complications and difficulties.
In this series, Anatomy of a Reaktor Project, I will continue the general theme of covering a philosophy of programming in Reaktor, while getting much more specific. In particular, I will focus on a current project of mine and it’s design from the ground up.
While this first part contains nothing in the way of actual code, it is still quite advanced in terms of content and ideas. As such, the reader should have a decent understanding of the existing modules in Reaktor. I’ll be laying out many of the problems that needed to be solved to implement my project, and next week we’ll get around to tackling them.
OUTLINE YOUR GOAL
As I mentioned in Programming and Design in Reaktor, it is important to have a pretty good idea of what you are trying to accomplish before you start. In this section, I’ll outline the idea that I had before doing any programming at all.
I was mostly inspired to create this ensemble by another product from Native Instruments, Battery:
A large part of Battery’s interface is a grid. Each ‘cell’ in the grid has one or more samples, a MIDI range (MIDI notes that trigger the cell to play back those samples), and a plethora of other options that are mostly immaterial to my project.
The controls are visible for only the selected cell at any given point in time, allowing for a program with literally hundreds if not thousands of knobs, yet each is still quite easy to find.
I had the idea that I wanted to make something similar to Battery in Reaktor, but instead of playing back samples, to synthesize drum (and other) sounds using a synth engine. In that sense, the project also bears much resemblance to the Kong drum machine, which is a part of Propellerhead’s Reason:
I provide pictures of these similar products because it is important to look at what has come before you – for inspiration, to look for anything obvious you may have missed, to decide what will differentiate your work from existing products, etc.
Chances are, Native Instruments and Propellerhead both have people working for them that are more talented than you. You can gain a lot by looking at their work.
I decided I wanted to have a grid that can change size according to the user’s wishes, like Battery, to a maximum of 128 cells at once. In addition, cells should be able to ‘overlap’ in MIDI range, so that a single note can play multiple sounds at once. Finally I decided, that like Kong, my project should have several synth engines dedicated to specific sounds.
There are some ‘simple’ ways to achieve something similar to what I wanted to create, but they all have serious shortcomings that I was unwilling to overlook.
The most obvious method, was that each cell could have a macro with all the appropriate controls, and to hold the macros in a larger Stacked Macro module, so that only one is visible at a time.
Despite it’s simplicity, I knew immediately such a scheme would cause trouble for me down the road. What happens when you have a macro that has been repeated 128 times, and you decide to make a simple adjustment, such as changing the position, name, or range of a knob? You are then left with the unsavory task of either changing the macros by hand individually, or copy/pasting the new version.
While copy/pasting may save some time, it also erases any snapshots you may have stored, since you have deleted the knobs that held the data. Worse, the fact that we will be adding sound engines one at a time (just thinking realistically here) means this whole process is guaranteed to play itself out several times throughout the course of making an ensemble.
In short, working with Stacked Macros in this manner is a mess unless you have a final design completed.
I decided, therefore, to design a knob type that could hold 128 values in an Event Table. The idea is, therefore, when the user selects a cell to be made visible, that value is recalled and sent to the knob.
Any change to the knob value from that point is made to the value in the appropriate index in the Event Table. An incoming MIDI note checks the MIDI range of each cell and, if within that range, reads out the appropriate data and sends it to the chosen sound engine.
This is an example where planning ahead can really save you a lot of time and trouble later on down the road. I’ll show how I designed the knobs later on, but they are closely connected with the rest of the ensemble which needs to be explained first.
I decided that each synth engine would have 4 voices. I’m hoping to end up with around 8 engines, so that means up to 32 sounds could theoretically be played at once.
The MIDI implementation for this is a little complex – if we want everything to have 4 voices, then the ensemble must as well. However, we want to be able to send up to 32 note/gate combinations to our synth engines at once, and a 4 voice ensemble will not handle 32 voices!
Manipulating MIDI data to act any way other than the way that Native Instruments intends is often a fairly difficult task. For the purpose of this ensemble, I simply wanted a monophonic event stream that would send an event any time a MIDI note was received or released.
Unfortunately, the default MIDI handler doesn’t work like this! Let’s say you press MIDI note 60, then, without releasing, also press note 62. After pressing note 62, you release note 60. If you are using monophonic Note/Gate modules, neither will send an output when note 60 is released – they are monophonic and only focused on the latest received note, 62.
Once we have a monophonic MIDI stream, we’re going to translate it to be polyphonic anyway! We need to create a macro that controls a single synth engine, then duplicate it for each one. This macro will only receive incoming note data if that note is used to trigger the given engine.
When it does, it adds notes to a stack to determine which have been used most recently. The voice which has been inactive for the longest period of time will be chosen for the new data. This helps ensure that previously playing sounds will not be cut off by the start of new sounds.
Implementing all of this is the subject of a tutorial in itself, but one that illuminates many of the points that I’ve made previously about large instrument design. Next week, I’ll show how I designed the MIDI handlers, and hopefully start to talk about knob design as well. Thanks for reading!
Have a Question or Comment About This Tutorial?
Want to ask a question about this tutorial or perhaps you have something to add?
Click through to our forum post about this tutorial and join the conversation!
Visit: Anatomy of a Reaktor Project