Super Collision At Studio Dave: The New World Of SuperCollider3, Part 2

In the first part of this series I introduced SuperCollider3 and its most basic operations. Now let's make things a little more interesting by adding a little randomization, a neat GUI, and some MIDI control.

Creating A GUI

Let's add a simple GUI to control the synthesizer. We'll employ the services of a SuperCollider Quark called AutoGui to make things easy for us novices :

    a = SynthDef(\sinetest, {arg out = 1, freq = 440; Out.ar(out, SinOsc.ar(freq))}) ;
    z = SynthDefAutogui(\sinetest, scopeOn:false) ;


Easy, just two lines of code to produce the synthesizer control panel seen in Figure 1.

 

Figure 1. SuperCollider's AutoGui Quark at work.


As its name implies, the AutoGui class automatically creates a GUI to represent the elements of a SynthDef, i.e. a SuperCollider synthesizer definition. In the example, the SynthDef is built from our simple synth and an added output channel setter. AutoGui performs its magic on the SynthDef, and voila, we have a synthesizer with a graphic control panel, made with two lines of SuperCollider code.

AutoGui is one of many realizations of SuperCollider's GUI capabilities. Other interesting manifestations include Fredrik Olofsson's red* quarks, James Harkins' dewdrop library, the Crucial extensions, and the EZ-GUI classes. As in other aspects of the system, SuperCollider gives you more than one way to do the job.

 

photo of the hadron quark

Figure 2. The Hadron Quark on display. (Full size)

Before leaving our simple example let's look at something with a more ambitious GUI. Figure 2 shows off Batuhan Bozkurt's Hadron, a SuperCollider quark that include various GUI components. At first Hadron looks a little like SuperCollider in Pd's clothing, but Hadron is a personal system, not a general-purpose GUI. Like most examples of a SuperCollider GUI Hadron was designed originally for its creator's specific purposes, and thanks to its broader utility it's been packaged as a quark for other users to explore. My first experiments included the addition of more synths and effects processors on my canvas layout - with all states saveable and loadable - and I've started to look into the guidelines for writing my own Hadron plugins.

Notes On Notes

By now the sound designer might be a little interested in SuperCollider, but the composer might be wondering what the fuss is all about. Our tiny example merely plays a sine wave at a single frequency and a default amplitude value. However, consider the following code :

   a = {SinOsc.ar(Rand(200,400))}.play;

Now a different frequency value, randomized between 200 and 400 Hz, will be used for each run of the code. Composition-wise our example's getting a little more interesting, but it needs some repetition to get something like a phrase from it. The following code presents one solution - a Task - for generating a series of randomly selected tones :

    (
    SynthDef("Randy", {arg out = 0;    // Single-channel output.
        Out.ar(out,
            SinOsc.ar(
                // Randomize integer frequency values.
                Rand(200,400),       
                // Apply an amplitude envelope to each note.
                0, Line.kr(0.2, 0, 1, doneAction:2))   
            )
    }).send(s);    // Send the definition to the server.
    )

    (
    t = Task({
            16.do({
                    Synth.new("Randy"); 0.5.wait;   
            })
    }).play;
    )

When the Task is evaluated the synth named Randy will be played 16 times, each time at a different frequency, with half a second between notes. Now things are looking a lot more interesting to our composer, especially when she starts figuring out how to apply randomization to other variables, e.g. the wait time and the do length. She might get even more interested when she learns how to create a GUI for triggering this Task, but before we get further into SuperCollider's GUI capabilities let's look at its MIDI connectivity.

A Little MIDI, S'il Vous Plait

The next example takes our little sine-wave synthesizer and puts it under MIDI control. The example also introduces a more complex SynthDef, with a gate value added for constructing an envelope to shape the audio output for each note played, similar to the example above. I plugged an Akai LP25 keyboard into my laptop's USB port, then I opened the ALSA MIDI panel in QJackCtl to connect the LP25 to a SuperCollider MIDI input port. After evaluating each block of the following code I played a few notes on the keyboard and heard the now-modulated dulcet tones of our simple sine-wave synth :

    MIDIIn.connect;
    s = Server.local;
    s.boot;
    s.latency = 0;

    (
    SynthDef("sinetest", {arg out = 1, freq = 440, gate = 0.0;
        x = SinOsc.ar(freq);
        x = EnvGen.kr(Env.adsr, gate,Latch.kr(gate,gate)) * x;
        Out.ar(out, x);
    }).send(s);
    )

    x = Synth("sinetest");

    //set the action:
    (
    MIDIIn.noteOn = {arg src, chan, num, vel;
            x.set(\freq, num.midicps / 4.0);
            x.set(\gate, vel / 200 );
    };
    MIDIIn.noteOff = { arg src,chan,num,vel;
            x.set(\gate, 0.0);
    };
    )

(Props to the authors of the SuperCollider manual for providing the basic version of this code. However, a much better - and preferred - method may be seen in the Comments section, thanks to James Harkins).

Cool, and not too complicated. The documentation includes many other examples, so if MIDI's your musical medium you'll want to check out the relevant docs for more insight and useful code.

More Words About That GUI Stuff

SuperCollider's GUI elements are nicely integrated into the language, with considerable documentation regarding their use. The system is flexible, and only a little effort is required to bring older SuperCollider code into modern usage. Class redirection automatically assigns the GUI toolkit according to the recognized operating system, but the user can control the deployment of the supported GUI views.

SuperCollider 3.5 uses the new Qt interface elements for its default GUI. However, if necessary I can switch easily between Swing and Qt, and many code examples are written for cross-platform application. Being able to switch GUI views can be most helpful. For instance, if you try to open the SuperCollider Help document while the GUI is set to Swing you'll receive this error :

ERROR:_ViewRedirect_is_an_abstract_class_and_should_not_be_instantiated_directly._*new_method_not_valid.

You can solve the problem by momentarily switching GUI kits. Run GUI.qt, and you'll be able to access the Help files. Keep the help doc open, then run GUI.swing if you want to reassert Swing as the active GUI view for your project code.

SuperCollider's GUI capabilities have developed beyond those described in the book. Users familiar with SuperCollider should have no concerns - the Cocoa and Swing GUIs are still supported while the Qt graphics capabilities are integrated into SuperCollider's basic design. You can learn what GUI kits are present on your system by evaluating the GUI.schemes command in your favorite SuperCollider-savvy editor. My system returns this information :

    IdentityDictionary[ (swing -> class SwingGUI), (qt -> class QtGUI), (colpen -> class ColPenGUI) ]

which tells me that I have Swing and Qt as GUI view options. The dictionary also lists a specialized GUI class called ColPen that appears to be a component in the wslib quark but I've done nothing with it yet. The SuperCollider documentation indicates that it is also possible to construct GUIs from Emacs graphics widgets, though again I haven't yet experimented with that capability.

SuperCollider's GUI elements are components for constructing project-specific GUIs, i.e. you won't find a nice general-purpose SuperCollider front-end complete with knobs and sliders and other graphic elements. Typically you'll build your own GUI for your specific purposes, but if you need a starting point you can find one in the existing examples of project GUIs. They range from simple UIs with a few buttons and sliders to complex arrangements of controls in multiple windows, complete with colorization, text entry and number boxes, file selectors, waveform viewers, and other cool fancy graphics.

I promised to provide a code example that creates a GUI for controlling the Task previously seen in the Notes On Notes section. Here's the code, but you'll need to remove the .play command from the Task before the UI will work correctly :

    w = Window.new("A Task", Rect(400, 400, 200, 30)).front;
    w.view.decorator = FlowLayout(w.view.bounds);
    Button.new(w, Rect(0, 0, 100, 20)).states_([["Play/Resume", Color.black, Color.clear]])
      .action_({ t.resume(0);});
    Button.new(w, Rect(0, 0, 40, 20)).states_([["Pause", Color.black, Color.clear]])
      .action_({ t.pause;});
    Button.new(w, Rect(0, 0, 40, 20)).states_([["Finish", Color.black, Color.clear]])
      .action_({
        t.stop;
        x.release(0.1);
        w.close;
    });

Figure 3 shows off the results. It's not much to look at, but its code points to greater possibilities. And as we hoped, our composer friend is now much more interested in SuperCollider. She sees that she has complete control of the logic behind the buttons, something not possible with her commercial software, and her imagination has begun to process the implications of our little example.

photo of a task GUI

Figure 3. A GUI for a Task.


New users should read the Help system's Introduction To GUI, a guide to writing code for basic and advanced GUI construction. Consider it required reading if you plan on making your own GUIs for your projects. Some SuperCollider quarks include custom GUI components that are useful when considering your own interface designs. Interested users should look into the ixiViews, dewdrop_lib, crucial_lib, Hadron, and AutoGui quarks for some well-designed UIs. See also the Help files for the EZ-GUI classes, a handy set of graphic controls for fast interface development.

Outro, Part 2

Gotta go now, but I'll continue exploring SuperCollider's advanced features when I return. In the meanwhile you can download the latest official release - it may be up to 3.4.4 by now - or retrieve and build the source code for the unreleased version 3.5. Have fun, and I'll see you in a couple weeks.
 

______________________

Similis sum folio de quo ludunt venti.

Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

MIDIIn.noteOn vs. NoteOnResponder

James Harkins's picture

Nice! Note, though, that MIDIIn is the old-school way of receiving MIDI input and its direct use has been discouraged for quite some time now. Instead, the MIDIResponder set of classes is (usually) the better way to go.

//set the action:
(
n = [
	NoteOnResponder({ arg src, chan, num, vel;
		x.set(\freq, num.midicps / 4.0);
		x.set(\gate, vel / 200 );
	}),
	NoteOffResponder({ arg src, chan, num, vel;
		x.set(\gate, 0.0);
	})
];
)

// clean up later
n.do { |resp| resp.remove };

The reason is that you can add and remove MIDI responders at will, whereas this is a lot more difficult with MIDIIn.

Author's reply

Dave Phillips's picture

Thanks, James. Yep, I took the Old School approach while I'm still getting the hang of the New School. :) You're right, the Responders are a much better solution. Thanks also for the clear example.

Best,

dp

Similis sum folio de quo ludunt venti.

Thanks!

J. Simon van der Walt's picture

I'm enjoying this series of articles, thanks. I've used SuperCollider for a number of projects, mainly on the mac, but also occasionally under Ubuntu on a netbook as well. Interested to see a fresh take on this really rather huge and deep 'ware.

White Paper
Linux Management with Red Hat Satellite: Measuring Business Impact and ROI

Linux has become a key foundation for supporting today's rapidly growing IT environments. Linux is being used to deploy business applications and databases, trading on its reputation as a low-cost operating environment. For many IT organizations, Linux is a mainstay for deploying Web servers and has evolved from handling basic file, print, and utility workloads to running mission-critical applications and databases, physically, virtually, and in the cloud. As Linux grows in importance in terms of value to the business, managing Linux environments to high standards of service quality — availability, security, and performance — becomes an essential requirement for business success.

Learn More

Sponsored by Red Hat

White Paper
Private PaaS for the Agile Enterprise

If you already use virtualized infrastructure, you are well on your way to leveraging the power of the cloud. Virtualization offers the promise of limitless resources, but how do you manage that scalability when your DevOps team doesn’t scale? In today’s hypercompetitive markets, fast results can make a difference between leading the pack vs. obsolescence. Organizations need more benefits from cloud computing than just raw resources. They need agility, flexibility, convenience, ROI, and control.

Stackato private Platform-as-a-Service technology from ActiveState extends your private cloud infrastructure by creating a private PaaS to provide on-demand availability, flexibility, control, and ultimately, faster time-to-market for your enterprise.

Learn More

Sponsored by ActiveState