This helpfile is part of a GUI tutorial.
It is the second part of a beginner's introduction to SuperCollider's GUI system. First part covers creating a window, while third part talks about composing views with basic GUI components.
This is a tutorial to get started using SuperCollider's GUI system to create views and make them interact with a Synth.
It covers the following topics:
You will need to boot the Server and add a SynthDef to it which we will be using in this tutorial.
The SynthDef is a simple sine wave with a percussive envelope.
We will control the frequency, volume and the duration of a Synth.
You can try the synth using:
We'll start with the following code which is not yet connected to our synth and will therefore not yield any sound yet:
If this code does not make sense to you, you can find more explanations about it in GUI: Create a Window.
So we start with a simple button, that, sadly, is not very useful so far. To connect it, you need to assign a function to its 'action' method.
As we already knew the command to play the synth, we just have to configure the button to evaluate this command when it is pressed. It is also posting a message to the console, which might be useful for debugging purposes.
We now have a keyboard, but not a very good one ! It only has one key... I'd say that might be enough, but that's quite uncommon.
So let's add a second key:
As you can see, the Layout has arranged everything automatically.
But copy-pasting is not a good way to add keys. Instead, we can just ask SC to create a button 8 times:
Those buttons feels too small. This is because Button has a low default maximum height. We can change it by reassigning it:
So we now have 8 buttons, but they all make the same sound. That's doesn't sounds like much progress to me.
We can change the Synth parameters by modifying its arguments:
We just need to introduce this inside the loop that creates the buttons. But instead of asking SC to do this 8 times, it will do it for a collection of frequencies instead.
We can transform a set of MIDI notes into frequencies and map them to the buttons:
Now that we have a keyboard, we'd like to implement a volume slider to the view. We can do this by inserting a Slider to the layout:
The volume slider now appears at the right of the piano, like it was a key. This is because it is on the same layout as the keys.
For now, the Window is only containing a HLayout.
The HLayout divides the Window horizontally, as if it was a succession of columns.
It will distribute the views inside those columns, one by one, from left to right.
This is why the Slider has been pushed all the way to the right. With this division, you can add things to the left, to the right, and between columns.
But you cannot order views vertically. For this, you need to create a VLayout, which in turns, cannot order views horizontally. To mix horizontal and vertical division of the Window, you will need to insert some layouts inside other layouts.
Let's see an example about layout hierarchy. Execute the following code before reading it to get a visual idea about the way it works:
The window is first divided vertically, then the bottom of the window is divided horizontally. This means there are 3 emplacements, occupied by 3 buttons. It can take some time to get accustomed to this logic.
Let's adapt our previous code to place the slider on top of the piano:
The slider is crushing everything ! It's because it is not on the right direction. We can fix this with the .orientation
method. Then we can also reduce its maximum height with .maxHeight
so it takes less space:
So far, we changed its graphical properties, but the slider do not have any action
. It's time to connect it:
In this case, the action
function of the Slider will assign the sliders value to a variable called volume
. When a key from our 'piano' is pressed, it will also check this variable to pass the right volume as argument, when evaluating the Synth command.
But how did the slider know what values were expected by the volume parameter ? Well it didn't. We were only lucky: Sliders value spans between 0 and 1, which is the correct setting for the volume.
But what if we want to control other ranges ? We can use .linlin
or .linexp
to map the sliders value, which is between 0 and 1, to a value between 0.1 and 2. We'll use this to new value to control the duration of the percussive envelope:
Alternatively, we can use a ControlSpec to do the same thing:
The last thing to do is to label our controls. It is easy to remember what the keyboard does, but the sliders could use some indications. We will use a StaticText for this, configuring its string, and its alignment.
You can see that when adding the views inside the layouts, I also specified a number. This is called assigning a 'stretch' to a view:
The stretch number defines the view's ratio relative to the sum of every view's stretch inside a layout. In our example, the keyboard has the same size as the rest of the views, because the keyboard has a stretch of 8, and the sum of every others views stretches is also 8.
This means that a view with a stretch of 3 will be 3 times bigger than a view with a stretch of 1. A view with a stretch of 6 will be 3 times bigger than a view with a stretch of 2, and 6 times bigger than a view with a stretch of 1.
Note that the minimum and maximum size of a view are also taken into account when using stretch, which can affect the real ratios of the views.
This has been a long tutorial, but with those basic concepts, you should now be able to manipulate every GUI Class without much difficulties.
The next tutorial in this series is a tour of common things you might want to implement when using GUI, for example an interface with tabs, allowing you to switch between different views. Like we did here, it is about using basic GUI components to create interfaces. You can access it here: GUI: Composing views with basic components.