Using Multi Displays in Reaktor Part I
The Multi Display module has a section in the FUNCTION tab of the properties labelled Objects. By default, there are 10 objects; for the purpose of this project, I changed that number to 64, which will be the maximum number of steps in our sequence.
An object can be several things – a cross, a line, a rectangle, a box (solid rectangle), or it can display a .tga or .bmp file. In this tutorial, we are going to use boxes to display the value of each step:
Each object has several parameters (Obj, X1, Y1, X2, Y2, R, G, B, and A) that describe it’s object type, position, and color on the screen. To set one of these values for a given object, you must first set the Idx input of the Mult Display to that object’s index value (ranging from 1 to the number of objects).
Any event sent to the Obj, X1, Y1, X2, Y2, R, G, B, or A inputs will change that value for the currently selected object.
However, by default, the Multi Display module has several boxes selected in the FUNCTION tab of the properties: Ignore Obj, Ignore RGB, and Ignore A. These boxes change the functioning of the Multi Display module in a way that was very confusing for me as a beginner, not realizing that they were there.
When the Ignore Obj box is checked, any event at the Obj input affects every object in the module. For example, if you set one object to be a box, they all become boxes. The Ignore RGB and Ignore A boxes work similarly. These options can be very useful. Since our project consists of a row of box objects with the same RGB and alpha values, we can simply set each of these values once, and they will control every object in the module.
Simple! Now each object is set to be a red, fully opaque box (-1 is the Obj code for box. You can find the rest of the codes by hovering over the Obj input with the mouse as long as the Show Info option is checked).
Now, we can finish a simple version of our step sequencer by using a mouse area to control the Idx, X1, X2, and Y2 values of the objects. The Y1 value will always be equal to 0, as it represents the bottom corner of the box we will draw (we can simply leave it unconnected to achieve this).
Make sure your Mouse Area has the same dimensions as your Multi Display module and layer it on top in the Panel view.
Next, I created a step knob with a range from 4 to 64 steps. Taking the reciprocal (1/x) of this value and using a Modulo and an Add module, I was able to scale the X output of the Mouse Area to range from 1 to the value of the Steps knob:
This value controls the Idx input of the Multi Display. Now the Mouse Area will control the objects indexed from 1 to the Steps knob value.
Now, the rest of the module is easy to connect to the structure:
After setting the Index, the X1 and X2 inputs are also supplied by the Modulo – each object takes up 1 unit of space along the X axis.
Next, the Y output from the Mouse Area simply runs straight into the Y2 input of the Multi Display module – the X output has already set the Idx and X positions of the object, so the Y value can simply connect directly.
Finally, the XR input is now controlled by the Steps knob as well. The XR input determines the range to display on the Multi Display (assuming the XO input is set to 0, it sets the maximum X value that will be displayed).
This is a clever trick to make it such that only the objects currently being used are displayed. When the Steps knob is set to 8, for example, the objects indexed at 9-64 should not be displayed. Since their X values lie outside the 0-8 range being displayed, they become invisible to us.
That was simple enough, and at a glance, it may work well enough too. However, there are substantial shortcomings in the code above, all of which can be fixed with a few extra modules and a little attention to detail.
If you’ve built the structure, you can follow along with the errors I’m about to describe (make sure you set the Multi Display module to ‘Always Active’). Otherwise, the download for this tutorial contains 4 versions of this structure, starting with the simplest one I described above.
The first problem I would like to point out, is that our sequencer does not save the data that it is given. So it won’t recall with a snapshot, and if we save and reload the ensemble, the sequence will be erased. We’ll fix this with a snapshot value array.
Another problem can be seen by drawing a horizontal line across the Mouse Area slowly, trying to keep the Y value the same while changing the X value. Even if you are moving very slowly, you can sometimes ‘skip’ over the value you should be drawing. I was initially very confused by this when I started working with the Mouse Area.
However, the problem is very simple. While drawing in a perfectly straight line, we are changing the X value (the Index), however the Y value is staying constant. When the Y value does not change, the Mouse Area does not output a value at the Y output.
Thus, the X value changes, and sets the index, preparing us to write values, but we never write anything and simply move on to the next index. Fortunately this is an easy problem to fix.
The final problem with this code can be found by moving very quickly in a diagonal line across the mouse area. Like before, you will find it is easy to ‘skip’ over objects that look like they should be written to, even though this time, the Y value is changing.
The culprit is again the Mouse Area, which does not output every point along the line we are drawing, but simply gives us a regular snapshot of the X and Y positions of the mouse if a button is pressed. This is the most complicated of the bugs to fix, but it is still a fairly simple patch.
The first problem I identified is that we aren’t saving our data. This is easy to fix – we can simply insert a Snap Value Array to hold the values for us:
I’ve highlighted the Snap Value Array so you can see all of the connections easier. The Array simply intercepts all of the data going to the Multi Display, saves it, and sends it on it’s way. On loading a snapshot, the array will output all of the data for that snapshot, allowing us to save and recall as many sequences as we like.
It is important to change the size of the Array to 64 in the FUNCTION tab of the properties. By default a Snap Value Array has 2 values, so if you find yourself drawing only 2 boxes at a time that is probably your problem.
One last thing I’ll mention is that previously the X2 input had been equal to the Idx input minus one. I’ve subtracted 0.75 instead here, to create a small buffer between each box. I just think it looks better this way (check out the panel view to see the difference).
ALWAYS WRITING A Y VALUE
The next problem I pointed out is that you can draw over an object very slowly without ever re-writing it’s value. This can be fixed using 3 modules – an Order, a Value, and a Merge:
Since nothing after the Snap Value Array has changed I simply cut that part out of the picture. The Order module is left highlighted so you can see how it connects.
We’ve simply restructured our code so that any time we get a new index event, that object’s value is written to the last available Y value. This way, when we draw slowly in a straight horizontal line, we don’t encounter any bugs like before.
ALWAYS WRITING AN X VALUE
As I mentioned above, there is also a bug when drawing too fast to the Mouse Area. The Mouse Area only outputs events every so often, so it is easy to miss an index or two while quickly scrolling across the Mouse Area.
I created a simple macro to fix this:
This macro takes the index value leading into the Snap Value Array, and makes sure that every index between the current index and the previously received index value gets triggered on each event.
There is one simple trick I would like to mention, however. Notice the Router module – it’s purpose is that, on a new mouse click, you don’t want this macro to trigger. You simply want to output the current index – it does not matter what the previous index was because you have not been drawing a line, you are clicking the mouse for the first time.
On a new mouse click, the first X and Y outputs of the Mouse Area will actually fire before the L output turns to 1. So the first index on a new mouse click gets passed thru this macro. Each successive X output goes thru the Iteration module to make sure each index that has been drawn over since the last event gets drawn.
This macro can be inserted into the structure like so:
I’ve inserted a new Value module directly before it. This ensures that the new macro only gets triggered when an event comes from the Mouse Area. Without the Value module, you could trigger the macro with the Steps knob, which would introduce more bugs to our code by overwriting data when the knob was turned!
Okay, so now we have a structure that allows us to draw a bunch of boxes to the screen. But we still need a way to use the information that we are storing. Fortunately this is very simple:
Make sure you set the Event Table to have a table size of 64 on the X-axis.
Now, our macro has an index input, and it simply returns the value at that index for each event it receives. I used a Modulo to wrap the index inputs if they are out of range, but there are other ways to handle this.
Please note that while the Multi Display module has indexes from 1 to the number of Objects, the Event Table has an index from 0 to the number of Objects – 1. So if you have 8 steps in your sequence, you want to read indices 0-7 from the macro.
You can download my work from this tutorial here. There are 4 copies of the macro we made today, starting from the simplest version I described at the top. I included the copies with the bugs so that users can see the evolution of the macro and understand the bugs for themselves if they aren’t building along. The buggiest copy is at the top, the cleanest at the bottom.
I am going to be referring to this structure in a few upcoming tutorials. While I have called it a step sequencer, it could be used to control the partials of a Sine Bank module, or simply as a replacement for a bunch of knobs. I’ll be sharing some uses for it soon.
I hope you have found this tutorial useful. As you have probably discovered, programming Multi Display modules requires a careful attention to detail and a good understanding of how events work in Reaktor.
If you have any questions, or suggestions for improvements or Multi Display tutorials you would like to see, please let me know in the comments.