Making New Synths from SuperCollider SynthDefs?

Anyone got a SuperCollider example for a full Sonic Pi synth?

As Discourse correctly points out, this is similar to the thread about SC’s Ping Pong. It also relates to a thread about wavetable synthesis. In both cases, @ethancrawford is involved, so maybe it should be more of a direct interaction.

A while back, created two simple synthdefs in SuperCollider. Was able to load them in Sonic Pi and play with them like normal synths, but several opts are missing, especially the _slide ones.

Always thought that Overtone was doing something clever to add these things. As @samaaron pointed out last night, it’s not the case.

That was kind of an epiphany, for me.
Decided to go back to those SuperCollider-based projects during my office hours (which just ended, actually).
Thing is, haven’t got a clue how to get the other opts to work with new synthdefs. The Overtone/Clojure files (say, basic.clj) are full of references to these _slide opts and it’s really not obvious how they’re used in the synths themselves.

An example would greatly help.

For reference, here’s my “talking drum” synth. A clue about fitting things like note_slide would probably help me a lot to figure out the rest. (Would then attempt to create other synths from physical modelling and/or single-cycle waveforms.)

Thanks!

(
SynthDef(\tama,
         {|note = 52, amp = 1, out_bus = 0, pan=0.0, gate=1, tension=0.05, loss=0.9, vel=1, dur=1 |
		var signal, freq;
		var lossexp=LinLin.ar(loss,0.0,1.0,0.9,1.0);
		var env = Env([0, 1, 0.5, 1, 0], [0.01, 0.5, 0.02, 0.5]);
		var excitation = EnvGen.kr(Env.perc, gate, timeScale: 1, doneAction: 0) * PinkNoise.ar(0.4);
		freq=note.midicps;
		signal = amp*MembraneCircle.ar(excitation, tension*(freq/60.midicps), lossexp);
		DetectSilence.ar(signal,doneAction:2);
		signal = signal * EnvGen.ar(Env.perc, gate, vel*0.5, 0, dur, 2);
		signal=Pan2.ar(signal, pan);
        Out.ar(out_bus,signal);
	}
).writeDefFile("/Users/alex/Desktop/sc-synths")
)

Hi @enkerli. Don’t have time to provide an example right now, but the slide opts are used in the Overtone synthdefs as parameters to the (varlag ...) function, corresponding to SuperCollider’s VarLag UGen.

1 Like

Didn’t realize VarLag was a UGen! That makes more sense, now!

w00t! Got it!

Here’s the current version (with slide) of my tama-style “talking drum”:

(
SynthDef(\tama,
         {|note = 52, 
		note_slide = 0, note_slide_shape = 1, note_slide_curve = 0, amp = 1, amp_slide = 0, amp_slide_shape = 1, amp_slide_curve = 0, pan = 0, pan_slide = 0, pan_slide_shape = 1, pan_slide_curve = 0, attack = 0, decay = 0, sustain = 0, release = 1, attack_level = 1, sustain_level = 1, env_curve = 1, out_bus = 0, gate=1, tension=0.05, loss=0.9, vel=1, dur=1 |
		var signal, freq;
		var lossexp=LinLin.ar(loss,0.0,1.0,0.9,1.0);
		var env = Env([0, 1, 0.5, 1, 0], [0.01, 0.5, 0.02, 0.5]);
		var excitation = EnvGen.kr(Env.perc, gate, timeScale: 1, doneAction: 0) * PinkNoise.ar(0.4);
		note= VarLag.kr(note, note_slide, note_slide_curve, note_slide_shape);
		amp= VarLag.kr(amp, amp_slide, amp_slide_curve, amp_slide_shape);
		pan= VarLag.kr(pan, pan_slide, pan_slide_curve, pan_slide_shape);
		freq=note.midicps;
		signal = amp*MembraneCircle.ar(excitation, tension*(freq/60.midicps), lossexp);
		DetectSilence.ar(signal,doneAction:2);
		signal = signal * EnvGen.ar(Env.perc, gate, vel*0.5, 0, dur, 2);
		signal=Pan2.ar(signal, pan);
        Out.ar(out_bus,signal);
	}
).writeDefFile("/Users/alex/Desktop/sc-synths");
)

And here’s a slide, with that synth, after loading the SynthDef (and making sure Sonic Pi is set to accept external synths):

use_synth "tama"
use_synth_defaults tension: 0.045, loss: 0.99999, dur: 3, note_slide: 0.5, note_slide_shape: 7
s=play 36
sleep 0.5
control s, note: 62
sleep 0.5
control s, note: 50
sleep 0.5
play 50

Can now investigate some of the other UGens to create more synths. Will surely go overboard with those, but they really can be a lot of fun.

Thanks again, @ethancrawford! The notion that VarLag.kr was a UGen opened up this thing which has been nagging me since last November!

1 Like

Check out the docstring for load_synthdefs :slight_smile:

You mean, the example in the help file? It does explain the basic structure of a SynthDef file, but my problem has been with some of the “idiomatic” opts, especially the _slide* ones. @ethancrawford gave me the right clue about VarLag.kr as UGen. Still a bit puzzled by a few things (like delay_level and amp_fudge). But at least it works with my trusty old “tama” synth.

decay_level is one of the opts that can be passed into most synths (see Section 2.4 of the tutorial if that helps.)
amp-fudge is just a value internal to the synthdef that was being used to adjust the amp slightly.
Does that clarify it any more?

Not really, to be honest. But it’s all good. Will eventually figure things out. Your previous insight gave me a boost.

My issue with decay_level is that it sounds like it’s going through select, in the Overtone code. Not completely sure if it’s Select.kr in SuperCollider and, if so, if it’s selecting between the polar opposite of the value (-1), the value itself, and the sustain level. So, haven’t added that line to my tama SynthDef.
Since amp_fudge is set to 1, been ignoring it. It does sound like it might not be needed.
Tried doing something with the clarinet wavetable, but Sonic Pi is acting as though this SynthDef didn’t exist. It loads the other SynthDefs but this one produces no sound (though it does work in SuperCollider). Might be related to loading the table in memory, as you were discussing in the other thread.

Thanks again!

Yep, it’s Select.kr. The first parameter to select is the index of the item to choose out of the following array. So if decay_level = -1, (= -1 decay_level) will essentially return 1 for true, and it chooses sustain_level. (The element at index 1 in the [decay_level sustain_level] array).
Clear as mud?

Hi Alexandre, hi Ethan,

just wanted to mention that I am very interested in this discussion. Some time ago I did start with a synth definition based on some SC resources for a Fender Rhodes synth. You might remember. I just started to find my way into SC (so I will surely not be of any help soon if at all); as soon as my time allows it I will dig deeper.

So I am very grateful to gain some insights from this thread…

2 Likes

I was just playing with Supercollider and was going to post to see if anyone else has played with making their own synths and using them in SP. And here we are!

I’m just going through the basic tutorials on SC right now, so I’m nowhere near ready to start building synths, but I’m also interested in how others are getting on with this.

1 Like

Haven’t touched SC in a while and these attempts remained quite incomplete. Especially in terms of getting all these slides in. At the time, I had related questions about wavetables. There are neat ways to do wavetable synthesis in SC. Not so obvious how to make all of it work in SPi.
So, let us know about your experiments. Even if Discourse warns us before reviving old threads, it feels to me like this community would be ok with that.

1 Like

Thanks for responding. I know it can be done, but not sure if I’ll have much time till the summer to go down that particular rabbit hole! But perhaps with the thread revived a bit, others will see and post their experiences.

Hi folks.

It is definitely possible to make wavetable synthesis work in Sonic Pi. However, it’s not just as simple as adding a new SynthDef - there’s a bunch of supporting code that needs to be added to Sonic Pi to handle it too. I built a POC a couple of years ago that enabled a basic wavetable SynthDef to be played, but this work has languished a little, over the design of a suitable syntax to provide to the user, amongst other things.
Here is the WIP if you are curious - (It’s a little out of date, as for example we’re not using Overtone to build Synths any more, and I haven’t brought it up to date with latest master for a while):


I’m keen to continue this work for sure - I imagine once the desired syntax is sorted out, the rest will be fairly easy to complete.

2 Likes

Hmm… :thinking:

To my ear, the most important part of a wavetable synth is probably about going from one position in the WT to another. (What some WT synths call “index” and might be associated with “morph”.) Aren’t there SC synthdefs which make this really transparent?

WT position needs to be a slidable opt and the interpolation needs to be really smooth.

In terms of syntax, pos_slide, pos_slide_curve, and pos_slide_shape make quite a bit of sense.

There could be… That’s not the fiddly part in adding wavetable functionality to Sonic Pi anyway - most of the extra work needed is for the surrounding plumbing for loading and referencing the wavetable files themselves.

pos_* sounds like a decent enough name for that opt - when it gets to that stage :slightly_smiling_face:

1 Like