Supercollider tips, Q/A

Take a look at the helpfule for Pbindef I believe that will allow you to change only one key value at a time.

1 Like

Saw this video by Eli Fieldsteel recently, maybe the linked scripts in the description will be useful?

1 Like

hi keno,

considering context here, i assume that by changing a single key in your Pdef, you mean modulating it in response to MIDI data.

you can’t change a key in Pbind after it’s been created and started playing. when you write e.g. \dur, 0.1 in a Pbind, that \dur will always be 0.1 — it can’t be changed externally. instead, you can plug special patterns into keys so that you can modulate the parameters you want.

the quickest way in the context of a Pbind is to use Pfuncn, which executes a function over and over again. in this case we write a function which repeatedly returns the value of a variable. changing that variable modulates the parameter in the Pbind:

var dur = 1.0;

    instrument: \synth,
    dur: Pfuncn({ dur }, inf)

// now setting 'dur' modulates the \dur key. example:\dur, { |val, num, chan, src|
    dur = val.linlin(0, 255, 1.0, 3.0);
}, 14);

this is convenient enough when you only have one parameter to deal with, but it gets out of hand when you have 20 of them. for a more scalable approach, i would lump all modulatable keys into a single big event that you can modify at will. use Pfuncn to return it repeatedly and ensure you’re getting the latest updates, and then use Pbindf to supply additional keys.

var baseEvent;

baseEvent = (
    dur: 1.0,
    freq: 440,
    amp: 0.1

Pbindf(Pfuncn({ baseEvent }, inf), *[
    instrument: \pad,
    filterfreq: Pexprand(1000, 8000, inf)

// now setting baseEvent[\dur] modulates the \dur key. example:\dur, { |val, num, chan, src|
    baseEvent[\dur] = val.linlin(0, 255, 1.0, 3.0);
}, 14);

an important limitation is that this will not modulate parameters continuously — parameters are only read at the beginning of each note. the patterns system is a discrete sequencer and doesn’t really have a conception of continuously running control signals. if you do want continuous modulation, let me know and i can describe how to do that instead. (my solution involves instantiating all synths inside a Group and calling .set on that Group, which automatically broadcasts parameter modulations to the synths.)


Thank you so much for your answer, @nathan! I was hesitating to use a global variable as described in the documentation because I considered it bad style.
Continous modulation sounds awesome. If you can spare some time, I’d like to have a look at your approach.

Wow, haven’t discovered it yet!

1 Like

Couldn’t you use Buses and change the values of the buses using MIDI and then use the Bus.index.asMap functionality to link the buses to the Pbind? That way you’d get continuous changes.

I’m a beginner at SC, and trying to figure BeatTrack out.
I want to track the bpm of an incoming signal in realtime. I’ve got this modified example code to work (a bit wonky, but still it works):

a = SynthDef(\help_beattrack, { |out, vol=0.0, beepvol=1.0, lock=0|
    var in, fft, resample;
    var trackb, trackh, trackq, tempo;
    var beeper;
    in =;
    fft = FFT(LocalBuf(1024), in);

	#trackb, trackh, trackq, tempo =, lock);

    beeper =, 1.0,, 0.15));, * in) + (beepvol * beeper), 0.0))


Now, my question is: how do I use the bpm extracted from the input in a sequence, using Pbind for instance? trackb, trackh and trackq each represent quarter notes, eight notes and sixteenth notes. But I don’t understand how to use their values in a sequence. Is there a way to simply convert trackb etc to a float or integer, and then insert it into TempoClock?

Yes, the best (simplest?) way to continuously change parameters of running synths in response to incoming midi (or other) data is to change the value of a control bus in response to the data, and map (.asMap) the control bus to whatever parameter you want to modulate.

Using events you can only change the value on the evaluation of the event, not continuously, so even if you use a Pfunc it’s still only updated at the start of an event.

For this you’ll want to use SendTrig to pass a value from the server to the client.

I haven’t used BeatTrack in a long time, but I think this should work for what you want to do:


t = TempoClock(120/60);

a = SynthDef(\help_beattrack, { |out, vol=0.0, beepvol=1.0, lock=0|
    var in, fft, resample;
    var trackb, trackh, trackq, tempo;
    var beeper;
    in =;
    fft = FFT(LocalBuf(1024), in);

	#trackb, trackh, trackq, tempo =, lock);

    beeper =, 1.0,, 0.15));, 0, tempo);, * in) + (beepvol * beeper), 0.0))


o = OSCFunc({ arg msg, time;
    [time, msg].postln;
	t.tempo = msg[3];
},'/tr', s.addr);


t.tempo.postln // post current tempo

This will set the tempo of TempoClock ‘t’ to whatever the currently detected tempo is on every quarter note tick of ‘trackb’.

If you aren’t familiar with the client/server relationship (it caused me, and every other beginner I know, lots of grief), check out Client vs. Server reference in SCDocs.


Oh also, I recommend using OSCdef for managing your OSC responders in the client.

OSCFunc is just there in the example because I cribbed the code for SendTrig help file, but I’ve had orphan OSC responders laying around causing me grief in the past using OSCFunc directly.

Thanks a lot, this was super helpful!
I got it working as I wanted it with a pbind-sequence by changing your code to:

t = TempoClock.default.tempo = 120/60;

I’m still new to both programming in general and supercollider in particular, and I’m sure there can be better ways than to change the default tempo, but hey it works!

Installed SuperCollider on my ChromeBook (Samsung Chromebook Plus V1 (with ARM processor)). The application installed through the CLI fine but I can’t seem to get the server running. I’ve tried a few things from googling but had no luck so far. Curious if anyone with a more thorough understanding of the Linux implementation in ChromeOS and SuperColliders operating requirements could help me figure out if this is possible or not!

hey SC users – sorry if this is a bit off topic, but some of us SC devs have put together a SuperCollider user survey:

would be appreciated if you could fill it out to help us decide on the best directions of development :slight_smile:

(let me know if this isn’t the right place to post and/or overall inappropriate for this forum)


SC runs fine on my chromebook, running Ubuntu 14.04, and I don’t remember any server hiccups in installation… What distro are you running? If Ubuntu, maybe this is helpful:

i’ve been trying to run it in ChromeOS. i’m not sure what the limitations are on Linux applications in ChromeOS at this point but i would imagine it has something to do with that or the ARM processor.

Which Chromebook do you have? Crouton or Crostini? Built-in audio?

I’m Chromebook shopping but I’m a bit hesitant to commit as it seems that Crostini has not yet implemented the AC97 codec required for onboard audio. This might be a non-issue with external USB audio, though.

Acer c720 with crouton. I use either the 1/8" headphone output or an external USB audio box like a focusrite if that’s what you mean.

How can I use the envelope of my synth to control a transform action (RTT, for example) in the Ambisonic Toolkit?
For example:\waveGenerator, {

	| out = 0, t_trig = 0, attack = 3, decay = 2, amp = 0.8, freqfactor = 0.75, doneAction = 2 |
	var sig;

	~waveEnv =, decay), t_trig, doneAction: doneAction);

	// Mix pink and brown noise for wave signal
	sig = ( * freqfactor) + ([0.2, 1, 0], [attack, decay], [1, -1]))) * (1 - freqfactor));

	// Apply envelope
	sig = amp * sig * ~waveEnv;
	sig = sig * 0.3;, sig);


I tried to pass ~waveEnv to the transform action (FoaRTT(sig, ~waveEnv, 0, 0)), which didn’t work out.
You can find my code repository on GitHub.

Is there a supercollider speech/voice synthesis code out there anywhere? (ideally text to speech)

I did some searching, but it seems my keywords (supercollider, voice, speech synthesis) are too generic.

In sc3-plugins, do a search for “LPC” (that’s Linear Predictive Coding). That’s the foundation of a lot of speech synthesis.

Also in sc3-plugins: FormantTable. “Returns a set of frequencies+resonances+amplitudes for a set of 5 bandpass filters, useful for emulating the main 5 formants of a vocal tract.”

Lately I’ve been trying to learn the MIDI loopback technique on Digitakt. There are few circumstances which would cause the device freeze and panic. I used the MIDI Monitor on Mac and found out that is because of some MIDI messages. For conveniences I want Pi to do the task as a MIDI filter/ blocker.
First I want to make it to filter out a Control Change message: CC 120 across MIDI channel from 1 to 15. I have read the MIDI guides but still I cannot find a concrete example for this task.
	\ccFiltering, {
		// Which function to block/ filter this CC message?
	120, 0..15

Do you guys know which func I should use?

Thank you.