Because SuperCollider can output DC voltages directly, I wanted to see how far I can get controlling a modular synth with CV. This allows me to bypass many of the Midi-to-CV tools, which I haven't had the best experiences with...
So far, I have quantised pitch, envelope generator, and trigger instruments.
d1 $ pitch "0 10 8 1" # scale "<12 31 8>" # orbit 0
pitch
allows a pattern of note values. scale
sets the amount of notes per octave. The pitch and scale values will be converted to 1v/octave
. Both pitch
and scale
can be paternised for some microtonal madness...
d1 $ env "-1 0.8@2 0.3@3 0.8@4" # orbit 0
env
will take -1/1 patterns and apply a smoothing transition on each step of the cycle. This output will be a bit 'steppy', and works best when put through a slew or glissando module.
d1 $ trigger "0 1 0 0 1 1 0 1" # orbit 0
trigger
will take a 0/1 pattern and return +5v signals for the 1
values. Use -1
if you need a -5v.
I posted the code here if anyone is interested: https://github.com/mashaal/superdirt-voltage
10 Likes
I gave this a try out today. Really cool!
I got all 3 synth defs to work as expected pretty quickly. I got hung up on audio routing in Supercollider for quite a while however. I'm a bit unclear as to the right startup.scd
settings and how they relate to these orbit
numbers.
I have a UAD Apollo and I'd like these going out of the ADAT connection to an Expert Sleepers module in my modular rack. The first ADAT channel is the 11th output on my sound card.
I setup the startup file as follows (I'm only placing the relevant items here):
s.options.numOutputBusChannels = 12;
~dirt.start(57120, [0,10,12,14,16,18]);
All of the orbits (0 through 11) head out of my sound card sequentially though. There is no jump between orbits 0 and 2 as I would expect. I then decided to keep tying larger orbits and when I got to # orbit 10
I was getting an error message from SC saying:
WARNING: SuperDirt: event falls out of existing orbits, index (1)
but it worked! The audio was routed to the correct ADAT destination. I could not get # orbit 2
to send out correctly (or any of the others either) though.
So it seems like an error in my orbit assignment in my startup? Or a bug perhaps? Or maybe it's weird behavior because your synth defs are mono I assume and orbits are definite as stereo pairs?
Let me know if you have no idea and maybe I can flag some others over.
And regardless, thanks for sharing these!
Ben
1 Like
Ahh.. I reallise that I am not using orbit
semantically. I think I will change it to channel
or something else...
Right now, orbit/channel
needs to match to an output on your device, by index. Here is what I use:
I have a aggregate device that has an ES-8, which I use for tidal, so 0-15 would be used as orbits/channels
Depending on how your audio devices output are setup, those indexes will need to reflect that.
I'm still using stereo channels in my startup.scd
, Besides for catering to how many channels you have, I don't think anything special needs to be setup for this. It can get a bit confusing when outputting both CV and stereo audio tracks. You have to keep a mental note of which grouped outputs are stereo audio, and mono CV.
Thanks for this, I'll update the code/documentation to make it a bit more clear. I'm going to have a crack at an ADSR envelope in SuperDirt next.
2 Likes
I've updated the synth defs to use channel
instead of orbit
now...
1 Like
Ah, I see.
So I have to do something like this:
s.options.numOutputBusChannels = 16;
~dirt.start(57120, [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]);
And great about the auto
synth def. I was going to suggest that!
Very cool.
Please post here if you make updates if you don't mind. I'd love to follow along
s.options.numOutputBusChannels = 16;
~dirt.start(57120, [0, 2, 4, 6, 8, 10, 12, 14]);
I still use my start up like this, so that my audio channels are stereo. I ran into heaps of strange gain issues when I tried running mono only for everything
With this setup, I can still route audio to # orbit 4,5,6 etc as stereo channels -- as well as route # channel 0, 1, 2, 3 as mono CV signals. I think its because I'm skipping the superDirt
orbit output, and jumping straight to CV output to the audio card itself (as superDirt doesn't have capability of DC atm?)
Will continue to post, but hit a bit of a road block with ADSR -- any help would be much appreciated!
That makes sense re: channels thanks.
What road block did you hit?
I'm not totally sure how to map a tidal cycle against a super collider envelope...
Env.adsr(0.001, 0.2, 0.25, 1)
will output a new ADSR envelope
I tried looking at various existing synths and issues, but i end up a bit more confused than I started... I think I need to get current position of envelope related to cycle length, and then turn that position into a 0/1 value...
(
SynthDef(\adsr, { | out, channel, attack = 0.1, decay = 0.5, sustain = 0.5, release = 0.5 |
var env = Env.adsr(attack, decay, sustain, release);
var gen = IEnvGen.kr(env, index???));
OffsetOut.ar(channel, DC.ar(gen));
}).add
);
Thats more or less my work in progress...
Similar issue: defining new synths with different envelope behavior · Issue #89 · musikinformatik/SuperDirt · GitHub
I think this needs to be used somewhere: IEnvGen | SuperCollider 3.12.2 Help
Wow, I got it in the end, this is much nicer...
d4 $ adsr 0.001 0.2 0.25 1 # x 0
You can patternise these crazily too, but the envelope will only generate once per cycle...
d5 $ adsr "<0.05 0.9>" "<0 0.4>" 1 1 # x 0
Will update the repo... I made a clock
instrument too!
3 Likes
I'm super interested in this, although I don't fully understand it! I'd love to have a way to control the envelopes when using things like chop
so that you can have a crossfade between slices, for instance. (I had a response to that question from Julian (telephon) in another forum, but I can't find that right now and couldn't make it work anyway.)
Which sound card are you using. I am asking since last time I checked that kind perk, not all cards were supporting DC voltage out.
Hmm.. I'm not sure exactly what you mean -- if you end up finding that example, I'd love to have a look...
I have an ES-8. There are a few other audio interfaces that have DC-coupled inputs/outputs -- but yes, they are required for this.
https://www.expert-sleepers.co.uk/es8.html
Pretty sure that all newish universal audio interface have DC coupled outs. Apollo X6 + for sure.
1 Like
Thank you for posting this, I just picked up the Expert Sleepers ES-9 and want to integrate Tidal with my modular so this is very helpful to know.
4 Likes
This is exactly where I checked, btw their website also hold a resource page for all "known" cards that support DC ouputs. Not a 100% reliable source, but AFAIK anyone owning a MOTU (not me) should be good to go. The page I am talking about: https://www.expert-sleepers.co.uk/siwacompatibility.html
Amazing, that ES-9 looks really nice, I have the older ES-8...
I've just started giving this code a workout myself, if you need any help getting this working, let me know. Also, any feedback/suggestions are welcome.
Oh, also, some of the code shared above is already deprecated... The latest is here: https://github.com/mashaal/superdirt-voltage
Thanks @mashaal!
Glad you got it sorted.
I got wrapped up in some other stuff for I'm going to give this new update a go soon.
Ben
1 Like
After playing with the adsr
, I realise that I have it hard set to only produce one envelope per cycle. I think I can update this so the occurrence of the envelope in the cycle can be patterned too., like a triggered adsr
..
d1 $ trig "1 ~ 1 1 ~ 1 ~" # adsr (range 0.1 1 sine) 0.5 0.5 0.5
In that example the attack time would grow for each triggered envelope over course of the cycle.
1 Like