My Profile Photo

Concrète Mixer


An internet radio station dedicated to shredded field recording ambience


Now playing


How I got to using ChucK

This is a brief outline of how I went from using ‘standard’ music making software and ended up coding in ChucK.

When I started looking at doing audio software development I looked at several options. The way I write it sounds like I went about this task in a very precise way, but in reality I drifted in and out of things, with some dabbling occurring after I had already settled on ChucK.

The intent of this post is to outline the “journey” I took in case it might be useful for others. The big caveat is that there’s nothing particularly definitive about the choices I’ve made or where I’ve ended up, so you’d be better in taking what’s written below as a starting point for your own evaluations rather than ignoring the options I passed on and going straight to ChucK.

Background

So until 2013 I’d spent the previous 11 years producing electronic music tracks of various kinds using AudioMulch, a nifty if decidedly lowkey (compared to Live/Reason/Logic/Yaddayadda) program for Windows and (eventually) Mac. While I enjoyed using Mulch, its development ground to a halt in the early part of this decade and the project is now moribund. (In my view, an open sourced Mulch would be a killer app for Linux audio, but I don’t think that will happen.)

After a decade of Mulching I was keen to try something different. I dined with the devil and tried Ableton Live, but I’ve never been keen on following the herd (however excellent their choice might be). I decided that if I was to make a change it should be radical, and I should try to make my own sound from as low a level as possible.

Priorities

  • Being increasingly time poor, I didn’t want to have to an entire sound app myself (except, briefly, when I had a dabble).
  • It had to be Linuxy, preferably free/open source
  • It had to be able to run on a Raspberry Pi, because I wanted to make a sound generating box.

The Evaluation

Pure Data

Pure Data is the open source implementation of Max/MSP (Max on a Mac seems to be the defacto standard for the academic end of audio programming). I didn’t really do much pd coding, but I did watch the bulk of the videos of one of Miller “MSP” Puckette’s introductory courses on pd, which I greatly enjoyed and highly recommend.

In the end I decided pd wasn’t for me. I was a bit reluctant about this, as pd is pretty cool, but coming from a web programming background I find pd’s visual programming paradigm a bit unintuitive, or at least more time-consuming to fathom. Also I’d become increasingly annoyed mousing about to make music.

Supercollider

I had a brief look at SuperCollider but found the code layout (everything is wrapped up in braces) a bit frustrating. Again, it’s something I could come back to if I had sufficient motivation. Also, cool name…

Web Audio API

The web audio API is a standard for rendering audio in web browsers. When I looked at it in 2013 it was reasonably raw and only properly supported by Chrome. The API is interfaced with javascript, and as someone who has worked in JS for some time that did appeal.

A digression about mobile apps and sound art

Several demo apps written using the API are available online, and they are impressive. If Android’s browser container supported it, there’s a good chance I might have written Concrete Mixer as a phone app.

Two years on, however, I’m now of the view that building CM as a mobile app would have been a mistake. I don’t like the idea of a sound producing app being one a hundred apps on a user’s phone competing for their attention. To my mind the task of rendering sound worlds is a serious business, and Raspberry Pis, even though they are inexpensive and to some extent disposable, still feel more appropriate for this endeavour. More honest, somehow.

Back to the Web Audio API

So yes, back on topic, my main feeling is that the web audio API is best used as intended for interactive multimedia, rather than an audio-only application. I also find the API itself a bit cumbersome (compared to ChucK, see below). I would pay more attention if there was an implementation of it in nodejs but as far as I’m aware there’s nothing available that isn’t alpha.

Again, there may be reasons in the future to use it, but not right now.

Perl

Mid last year after I went on a tangent learning some audio processing techniques without ChucK doing the heavy lifting. I did this in Perl because it’s what I use in my day job and I wanted to save time. I ended up having a good fiddle and may write up a report on my experiments later. However I soon concluded that Perl isn’t the best platform for doing this long term.

ChucK

In the end I went with ChucK because it’s the simplest, most intuitive (for me anyway) language I came across. (This doesn’t mean it’s the best.)

So ChucK is a C++ish OO scripting language which describes itself as “strongly typed and strongly timed”. Time is tamed with the use of the dur (duration) type as well as being able to delay execution in a very ‘timely’ (teehee!) context:

1
2
3
4
5
6
7
8
9
441::samp => dur interval; // 441 samples or 1/100 of a second

while ( 1 ) { // ie do this continually
    interval => now; // wait for this duration to pass
    <<< "I waited", interval, "samples and then I did something" >>>; // log to stdout

    // will print the above message 100 times a second
    // you would never want to do this
}

It should be reasonably clear that this is perfect for scheduling and sequencing changes in signal - be it pitch, timbre, silence, etc.

ChucK’s other eccentricity is the => ‘ChucK’ assignment operator, which both assigns variables (back to front) as well as links audio components in the same way you might plug a guitar into an amp and from an amp into a mixer:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
// this listing demonstrates various uses of the => operator

// declare signal generating/filtering elements
// in ChucK parlance these are generically called Ugens.
// instantiate a sawtooth oscillator called saw
// and a low pass filter called low pass
SawOsc saw, LPF lowpass;

// set the gain of the sawtooth osc to a quarter of maximum
// it is strongly advisable to do this
// note scale is logarithmic so this is actually -12ish decibels
0.25 => saw.gain;

440 => saw.freq; // initialise the oscillator frequency to A4
// note saw.freq(440) does the same thing
4000 => int inty; // variable assignment

// set the lowpass filter to 4Khz (frequency response will roll
// off above this value with a steepness according to the filter
// type
inty => saw.freq;

// route saw oscillator to lowpass and then on to the soundcard output
// and route that to the sound card (dac)
saw => lowpass => dac;

// note you can declare and chuck at the same time, so we could have gone:
// SawOsc saw => LPF lowpass => dac;

while ( 1 ) { // loop forever
    // Get some sample hold going

    // randomly assign the oscillator frequency
    Std.rand2f( 20, 4000 ) => saw.freq;

    // randomly assign the filter frequency
    Std.rand2f( 20, 4000 ) => lowpass.freq;

    // finally, move time on
    // you can define duration in both increments of time and samples
    0.5::second => now; 
    
}

ChucKing durations to now means advancing time. Once you have your components in place they will do their thing (ie oscillate or filter) without you having to worry about them doing it.

When I studied ChucK all this made intuitive sense to me. Consequently I’ve ended up using ChucK for most of my recent tinkering.

Downsides

ChucK is 10 years old, and you’d expect a language of that age to be mature. However ChucK’s developer and userbase is small, and academic, and ChucK thus has few pressures on it. Development has focused on a narrow range of applications, notably “live programming”. I don’t dispute the suitability of this narrow focus, but it also means that ChucK often feels like a ‘toy language’, missing many features you’d expect. I guess I had better give examples:

  • Barebones syntax, eg no case statements or much in the way of syntactic sugar.
  • No base library loading - you need to explicitly load every library file you want access to. You can’t just provide ChucK with a lib directory environment variable and have all libraries in that directory loaded automatically.
  • A lack of file system tools (for example, there is no way in ChucK to access the file system, other than to load ChucK files).
  • A lack of concern for memory leakage, or performance generally (a major problem for a sound system like Concrete Mixer which is intended to run indefinitely on a Raspberry Pi).

As mentioned before these drawbacks lead me to use a Perl wrapper to manage Concrete Mixer. This hasn’t been a massive inconvenience, but it would have been nice if Concrete Mixer could have been pure ChucK app.

On the whole

My criticisms of ChucK are (in my view, obviously) reasonable, but I suspect if I had gone with any of the alternatives I could compile a list of different but equivalent drawbacks for them too, so singling out ChucK in this way is a little unfair. The fact is I’m still using ChucK and I’ve barely scratched the surface of its audio manipulation capabilities. I’m also unlikely to jump ship to another language any time soon. Although if you do know of something you think is better, let me know!

comments powered by Disqus