Other things on this site...

[Blog archives] [Categories]

How to package SuperCollider for Debian and Ubuntu Linux

SuperCollider works on Linux just great. I've been responsible for one specific part of that in recent years, which is that when a new release of SuperCollider is available, I put it into the Debian official package repository - which involves a few obscure admin processes - and then this means that in the next releases of Debian AND Ubuntu, it'll be available really easily.

These are my notes to help others understand how it's done.

First a few words: on Ubuntu you can also make SuperCollider available through an Ubuntu "PPA", and there's even a sort-of-official PPA where you can get it. Some people like this because it happens much quicker (there's less official approval needed). I strongly advise maintainers: it's really valuable to go through the Debian official repository, even though it's slower. There's no need to feel rushed! Getting it into Debian often means fixing a few little packaging quirks to make sure it installs nicely and interoperates nicely, and your work will result in much wider benefit. It's OK to do the PPA thing as well, of course, but you mustn't rely purely on the PPA. (You may as well do the debian thing and then repurpose the same codebase for PPA.)

The things I'm going to cover, i.e. the things you'll need to know/do in order to get a new SuperCollider release into Debian, include:

  1. joining the debian-multimedia team
  2. debian's lovely way of using git together with buildpackage
  3. importing a fresh sourcecode release of SC into the git
  4. compiling it, checking it, releasing it

But I'm mainly going to do this as a step-by-step walkthrough, NOT a broad overview. Sorry if that means some things seem unexplained.


I'm an Ubuntu user normally, but to keep things clean I do this work in a Debian virtual machine, by using Virtualbox. Ubuntu is based on Debian so you might think you can do it directly in Ubuntu but in practice it tends to go wrong because you end up specifying the wrong versions of package dependencies etc.

Of course, Ubuntu "inherits" packages from Debian, so after we push the Debian package it will magically appear in Ubuntu too.

In the debian you'll also need these packages, which you can get from apt install as normal:

  • build-essential
  • git-buildpackage
  • cmake

You'll also need to install whatever is needed ordinarily to compile SuperCollider - check the readme. (There's a tool mk-build-deps which can help with this, as long as the dependencies haven't changed since the previous SC.)


The Debian "multimedia team" has a special git repository of their own, which contains the released version of SuperCollider plus the debian scripts and metadata.

Here are shell commands for fetching the git repo and specifically checking out the three branches that are used in debian's git-buildpackage workflow:

git clone https://anonscm.debian.org/git/pkg-multimedia/supercollider.git
cd supercollider
git checkout -b upstream origin/upstream
git checkout -b pristine-tar origin/pristine-tar
git checkout master

If you do those "ls" commands you get a rough idea of what's in the 3 branches:

  1. "upstream": this should be the exact same as the contents of the "-Source-linux.tar.bz2" sourcecode downloaded from the main SuperCollider release.
  2. "master": this is the same as upstream EXCEPT that it has the special "debian" folder added, which contains all of the magic to compile and bundle up SuperCollider correctly.
  3. "pristine-tar": the file layout in here is very different from the others. It's simply an archive of all the source code tar files, created automatically.

This might seem a bit arcane, but don't change it - the debian "git-buildpackage" scripts expect the git repo to be laid out EXACTLY like this.

A shortcut that actually pulls all three branches is provided by gbp:

gbp clone https://anonscm.debian.org/git/pkg-multimedia/supercollider.git

but I'm doing it explicitly because it's kinda useful to get a bit of an idea what's going on in those three branches.


Let's imagine the main SuperCollider team have released a new version, including putting a new sourcecode download on the website. IMPORTANT: it needs to be the "-Source-linux.tar.bz2" version, because that strips out some Windows- and Mac-specific stuff. Some people don't care about whether there's extra Windows and Mac cruft in a zip file, but the Debian adminstrators do care, because they monitor the code in the repository to be careful there's no non-free material in there etc.

Do this every time there's a new release of SuperCollider to bundle up:

  1. Run uscan which checks the SuperCollider website for a new source code download. If it finds one it'll download it, and it'll also automatically repack it (removing some crufty files that are either not needed or lead to copyright complications). It puts the resulting tar.gz in ../tarballs. You can run uscan --verbose and it'll show some text details that might help you understand what actions the program is actually doing.
  2. Run gbp import-orig --pristine-tar --sign-tags ${path-to-fetched-tarball} the path, for me at least, is ../tarballs/ followed by the actual tarball file. Make sure it's the "repack" one. The procedure will check with you what the upstream version number is. Is it "3.8.0~repack"? No, it's "3.8.0".
  3. Refresh the patches. What this means is, the debian folder has a set of patches that it uses to modify the supercollider source code, to fix problems. These patches might not apply exactly to the new code, so we need to go through,

    export QUILT_PATCHES=debian/patches
    quilt push -a
    quilt refresh
    quilt pop      # repeat refresh-and-pop until all are popped

    Did you run the last two lines again and again? Eventually it says "No patches applied".

    After this, it's a good idea to do a git commit debian to store any changes you made to the patches in a git commit of their own.

    You may need to remove a patch - typically, this happens if it's been "upstreamed". To do that, you can git rm the patch itself as well as edit its name out of debian/patches/series, then commit that. You may also find you need to make a new patch, to fix some issue such as getting the latest code to build properly on all the architectures that Debian supports.

    (Recently the debian admins have started using gbp pq to look after the patches. Maybe that's useful. I haven't got into it yet.)

  4. Create a changelog entry.

    gbp dch -a debian

Here's something that might be surprising: the changelog file is what tells debian which version of SC it's building. If it sees 3.7.0 as the top item, it tries to build from 3.7.0 source. It doesn't matter what's been happening in the git commits, or which source code you have downloaded. So if you're importing a new version you have to make sure to add a new entry to the top of the changelog. Hopefully the pattern is obvious from the file itself, but you can also look at general Debian packaging guidelines to understand it more.


First let's get gbp to build a debian style source package. (You may be wondering: we started with SuperCollider's original source code bundle, why are we now building a source code bundle? This is different, it makes a .dsc file that could be used to tell the Debian servers how to compile a binary.)

The main reason I'm telling you to do this is that it performs some of the build process but not the actual compiling. So it's a good way to check for any errors before doing the hardcore building:

gbp buildpackage -S --git-export-dir=../buildarea

This will also run lintian to check for errors in rule-following. Debian's rules are quite strict and you'll probably find some little error or other, which you should fix, then do a git commit for, then try again.

You can also then build proper binary debs:

gbp buildpackage --git-export-dir=../buildarea

This might take a long time. Eventually... it should produce some .deb files. It might even ask you to sign them.


  1. SuperCollider uses "boost" code library. SuperCollider comes bundled with a recent version of it, and the exact version gets updated now and again. Debian makes this a little more complicated - they don't want to use the bundled version, instead they want to use the version that's built in to debian. So if you look in debian/control you'll see some "libboost" dependencies specified. If SuperCollider's dependency has changed, you may need to update this to get it building properly. You'll also need to use apt install to fetch those boost dependencies.
  2. If SC source code files get renamed or the folders change, it's fairly common that you need to edit one of the text files in the debian folder to point it at the right thing.


You've successfully made the .deb files, i.e. the actual installable binaries. Install them on your system. You can do it using dpkg -i like you would with most deb files, or for convenience you can use the debi command which makes sure you're installing the whole set of packages you've built:

debi ../buildarea/supercollider_3.8.0-1_*.changes

NOTE that this installing step is "real" installing. If you're working in a virtualbox like I am then you're probably not worried about whether you'll be overwriting your existing SC. Otherwise do bear in mind - this install will overwrite/upgrade the SC that's installed on your system.

Once installed, run it, make sure the thing is OK.


In order to get this stuff actually live on the official debian package system, you need to do a few things. You'll need to join "debian multimedia team" as a guest (see their webpages for more info on that), and once you've done that it gives you permission to push your git changes up to their server:

git push origin master upstream pristine-tar
git push --follow-tags

Then after that you need to do a "request for upload" - i.e. asking one of the debian multimedia team with upload rights, to give it a quick check and publish it. You do this via the debian multimedia team mailing list. It's also possible to get upload rights yourself, but that's something I haven't gone through.


So there we have it. Thanks to Felipe Sateler and other Debian crew for lots of help inducting me into this process.

Interested in helping out? Whether it's SuperCollider or some other audio/video linux tool, the Debian MultiMedia team would love you to join!

P.S. some added notes from Mauro about using Docker as part of this

| supercollider |

SuperCollider inspired web audio coding environments

SuperCollider is an audio environment that gets a lot of things right in terms of hacking around with multichannel sound, live coding and composing the different structures you need for music.

So it's no surprise that in the world of Web Audio currently being born, various people are getting inspired by SuperCollider. I've seen a few people make pure-JavaScript systems which emulate SuperCollider's language style. So here's a list:

I think there's at least one I've forgotten. Please let me know if you spot others, I'd be interested to keep tabs.

So there are obvious questions: is this a duplication of effort? should these people get together and hack on one system? is any one of them better than the others? I don't know if any of them is better, but one thing I know: it's still very early days in the world of Web Audio. (The underlying APIs aren't even implemented fully by all major browsers yet.) I'm sure some cool live coding web systems will emerge, and they may or may not be based on the older generation. But there's still plenty of room for experimentation.

| supercollider |

Notes on how we ran the SuperCollider Symposium 2012

I've just uploaded my notes on how we ran the SuperCollider Symposium 2012 (10-page PDF). sc2012 was a great event and it was a privilege to work with so many great people in putting it together. I hope these notes are useful to future organisers, providing some detailed facts and figures to give you some idea of how we did it.

The document includes details of the timing of things, the budgeting, promotional aspects. I also include some notes about outreach, which I think is important to keep in mind. It's important for community-driven projects to bring existing people together, and to attract new people - and for something like SuperCollider which doesn't have any institution funding it and pushing it forwards, these international gatherings of users are 100% vital both for the existing users angle and the new users angle. Happily, both of these aims can be achieved by putting on diverse shows featuring some of the best SuperCollider artists in the world :)

Shout outs to all the other organisers, who put loads of their own time and enthusiasm in (see the "credits" page), and hi to everyone else I met at the symposium.

(If you weren't there, see also Steve's great photos of sc2012.)

| supercollider |

Cross-correlation signal detection in SuperCollider

If you had to communicate a digital message by playing sound across a noisy room, how would you do it?

That's basically one of the problems signal processing engineers have worked on for decades, and there are many good ways to do it (the same principles allow mobile phones to communicate in a "noisy" radio spectrum too). One thing you can do is spread-spectrum signalling, using a particular signature spread across various different frequency bands. For example, an upwards "chirp" can be more robust than a simple bleep at a single frequency.

I just found this code example I put on the sc-users mailing list. It's quite nice - you use an upwards-chirp and a downwards-chirp, and detect which one has happened, even though we deliberately add loads of noise. (The code uses a technical trick, where we can do cross-correlation signal detection by convolution with the time-reversed signal.)

Server.default = s = Server.internal;
~dursamps = 16384;
~dursecs  = ~dursamps / s.sampleRate;

SynthDef(\chirpup, { |dur=0.1|
       var sig = SinOsc.ar(Line.ar(1000, 10000, dur, doneAction: 2));
       Out.ar(0, Pan2.ar(sig * 0.1));
SynthDef(\chirpdn, { |dur=0.1|
       var sig = SinOsc.ar(Line.ar(10000, 1000, dur, doneAction: 2));
       Out.ar(0, Pan2.ar(sig * 0.1));
SynthDef(\chirprecord, { |dur=0.1, in=0, buf=0|
       var sig = In.ar(in);
       RecordBuf.ar(sig, buf, loop: 0, doneAction: 2)

~group_chirp    = Group.new(s);
~group_analysis = Group.after(~group_chirp);

// analysis

// OK now let's create a buffer, then put a frame of data in
~upbuf = Buffer.alloc(s, ~dursamps);
~dnbuf = Buffer.alloc(s, ~dursamps);
       Synth(\chirpup , [\dur, ~dursecs], ~group_chirp);
       Synth(\chirprecord, [\dur, ~dursecs, \buf, ~upbuf], ~group_analysis);
// ...wait for one to finish before doing the next:
       Synth(\chirpdn , [\dur, ~dursecs], ~group_chirp);
       Synth(\chirprecord, [\dur, ~dursecs, \buf, ~dnbuf], ~group_analysis);

// reverse them
~upbuf.loadToFloatArray(action: {|data| ~upRbuf = Buffer.loadCollection(s, data.reverse)});
~dnbuf.loadToFloatArray(action: {|data| ~dnRbuf = Buffer.loadCollection(s, data.reverse)});

// detection

SynthDef(\chirpdetector, { |in=0, upbuf=0, dnbuf=0, framesize=100, out=0|
       var sig = In.ar(in);
       var conv = [upbuf, dnbuf].collect{|buf| Convolution2.ar(sig, buf, 0,
framesize) };
       var smooth = 0.1 * Amplitude.ar(conv, 0, 0.2);
       smooth[0].poll(smooth[0] > 1, "UP");
       smooth[1].poll(smooth[1] > 1, "DN");
       Out.ar(out, smooth);

~detectbus = Bus.audio(s, 2);
x = Synth(\chirpdetector, [\framesize, ~dursamps, \upbuf, ~upRbuf, \dnbuf, ~dnRbuf, \out, ~detectbus], ~group_analysis);

// Let's add some noise too, to make it a difficult task:
~noise = {WhiteNoise.ar(0.3)}.play(~group_chirp);

// Now we trigger different types of chirp and watch how the output leaps...
// RUN THIS LINE OVER AND OVER, waiting imbetween:
Synth([\chirpdn, \chirpup].choose, [\dur, ~dursecs], ~group_chirp);

The original discussion is here on the sc-users mailing list.

| supercollider |

Dubstep bass in SuperCollider

Dubstep bass in SuperCollider, improveable:


    var trig, note, son, sweep;

    trig = CoinGate.kr(0.5, Impulse.kr(2));

    note = Demand.kr(trig, 0, Dseq((22,24..44).midicps.scramble, inf));

    sweep = LFSaw.ar(Demand.kr(trig, 0, Drand([1, 2, 2, 3, 4, 5, 6, 8, 16], inf))).exprange(40, 5000);

    son = LFSaw.ar(note * [0.99, 1, 1.01]).sum;
    son = LPF.ar(son, sweep);   
    son = Normalizer.ar(son);
    son = son + BPF.ar(son, 2000, 2);

    //////// special flavours:
    // hi manster
    son = Select.ar(TRand.kr(trig: trig) < 0.05, [son, HPF.ar(son, 1000) * 4]);
    // sweep manster
    son = Select.ar(TRand.kr(trig: trig) < 0.05, [son, HPF.ar(son, sweep) * 4]);
    // decimate
    son = Select.ar(TRand.kr(trig: trig) < 0.05, [son, son.round(0.1)]);

    son = (son * 5).tanh;
    son = son + GVerb.ar(son, 10, 0.1, 0.7, mul: 0.3);
| supercollider |

Efficiency in SuperCollider: pausing synths

When I use SuperCollider I often create synths and when they're done I free them, but I don't often pause them. For example, if you've got a synth playing back a recorded audio Buffer, and the Buffer ends, hey ho, no problem, I can leave it running and send a trigger when I want the sound to play again. But since I'm currently working with mobile devices I need to be more careful about that kind of thing.

Here's an example of what I mean. Run this code block to define two synthdefs, a playback one and a "supervisor":

SynthDef(\supervisor, { |targetid=0, trigbus=0, rate=0.25|
    var cycle, pausegate;
    cycle = LFPulse.kr(rate);
    Out.kr(trigbus, Trig1.kr(cycle, 0));
    Pause.kr(cycle, targetid); 

SynthDef(\player, { |buf=0, trigbus=0|  
    // Some meaningless extra cpu-load so we can see the difference
    var heavycruft = 400.collect{[WhiteNoise, PinkNoise, BrownNoise].choose.ar}.squared.mean;
    Out.ar(0, PlayBuf.ar(1, buf, trigger: In.kr(trigbus)) + (heavycruft * 0.00001))

Now when I use the player synth like normal...

b = Buffer.read(s, "sounds/a11wlk01.wav")   
t = Bus.control(s);
x = Synth(\player, [\buf, b, \trigbus, t])

...I can see the CPU load on my machine shoots up to 40% (because of the pointless extra load I deliberately added into that second SynthDef), and it stays there even when the Buffer ends.

(Often you'd tell your synth to free itself when the Buffer ends using doneAction:2 - that works fine, but in this case I want the synth to keep running so I can retrigger it.)

Having run the above code, now start the supervisor running:

y = Synth(\supervisor, [\targetid, x.nodeID, \trigbus, t], x, addAction: \addBefore)

This should repeatedly pause-and-restart the playback. When the sound is silent, the CPU load drops from 40% down to 0.1%. So, clearly it makes a saving!

So in order to do this I had to use Pause.kr() in the supervisor, and also to tell the supervisor which node to pause/unpause (using x.nodeID). The supervisor is also sending triggers to a control bus, and the player is grabbing those triggers to reset playback to the start.

| supercollider |

sc140: squeezing entire pieces of music into tweet-sized snippets

The New Scientist has a nice article about my sc140 project to highlight the amazing music that some people have been creating using the medium of Twitter.

This is all made possible by a rather lovely piece of software called SuperCollider, which is a programming language specialised for sound and …

| supercollider |

Reverse-engineering the rave hoover

One of the classic rave synth sounds is the "hoover", a sort of slurry chorussy synth line like the classic Dominator by Human Resource. I decided to recreate that sound from scratch, by reverse engineering the sound and recreating it in SuperCollider. Here's how to do it:

Step 1: Listening …

| supercollider |

SuperCollider Symposium 2009

Just back from the SuperCollider Symposium at Wesleyan. It felt like I was nonstop (did 2 talks, 2 workshops, 2 gigs! Hopefully no-one got sick of me) but there was lots of fascinating stuff to hear about and discuss. Some things:

Sciencey: Chris Kiefer's neural network classes were interesting …

| supercollider |

YMCA (NYC) and whether it's fun to stay at the

For budget accommodation in New York, I got a tip to try the YMCA. It was $90/night for a single room, which is not cheap although it is cheap for Manhattan. But did it live up to the claims? Let's examine the evidence:

  • "You can get yourself clean" - hmm …
| supercollider |