Skip to content

Instantly share code, notes, and snippets.

@peterkappus
Last active December 30, 2019 01:34
Show Gist options
  • Save peterkappus/8b582b70666b76e152d714c8c801a227 to your computer and use it in GitHub Desktop.
Save peterkappus/8b582b70666b76e152d714c8c801a227 to your computer and use it in GitHub Desktop.
Super Collider treasures
(
Server.default.options.device = "BlackHole 16ch";
//Server.default.options.device = "Built-in Output";
//ServerOptions.devices;
//handle large delay sizes
//s.options.memSize= 8192*2;
//s.reboot;
//initialize a midi client
MIDIClient.init;
//connect all the possible inputs
MIDIIn.connectAll;
~cutoff = 14000;
~release = 0.5;
~cutoff_chan = 1; //1 = modwheel;
~release_chan = 24;
~reverb_chan = 23;
//harmonics
//~channels = [17,18,19,20,21,22];
// A dictionary of channels with one for each harmonic voice.
// The keys are the channel IDs and values are the harmonic (multiple of the fundamental)
// defaults to 1, goes up to 12 (for now)
~harmonic_channels_start_index = 17;
~harmonic_channels = Dictionary.new;
6.do{
arg i;
~harmonic_channels[~harmonic_channels_start_index+i] = 1;
};
//~harmonic_channels.asPairs.asAssociations(SortedList).collect{|item| item.value};
MIDIdef.cc(\ccFunc, {
arg ccNum, chan;
[ccNum,chan].postln;
if(chan == ~cutoff_chan) {
~cutoff = LinLin.kr(ccNum,0,127,100,8000);
};
if(chan == ~release_chan) {
~release = LinLin.kr(ccNum,0,127,0.05,10);
};
if( chan == ~reverb_chan) {
z.set(\room, LinLin.kr(ccNum, 0,127,0.05,55));
};
if( chan >= ~harmonic_channels_start_index && (chan < (~harmonic_channels_start_index.asInteger + ~harmonic_channels.size))) {
var harmonic = LinLin.kr(ccNum,0,127,1,50);
~harmonic_channels[chan] = harmonic;
};
});
MIDIdef.noteOn(\noteOn,{
arg veloc,num,chan, vol;
vol = LinLin.kr(veloc,0,127,0.01,0.8);
[veloc,num,chan].postln;
//~bandwidth.postln;
Synth(\ping, [\vol, vol,
\note, num,
\harmonics, ~harmonic_channels.asPairs.asAssociations(SortedList).collect{|item| item.value},
\release, ~release,
\cutoff, ~cutoff,
\bandwidth, ~bandwidth
//\harmonic_channels, ~harmonic_channels
]);
});
// FreeVerb2 - demo synthdef
SynthDef(\FreeVerb2x2, { |out, mix = 0.25, room = 0.15, damp = 0.2, amp = 1.0|
var signal;
signal = In.ar(out, 2);
ReplaceOut.ar(out,
//GVerb.ar(signal, 10, 4, 0.5, 0.5, 10, 0.2);
FreeVerb2.ar( // FreeVerb2 - true stereo UGen
signal[0], // Left channel
signal[1], // Right Channel
mix, room, damp, amp
);
); // same params as FreeVerb 1 chn version
}).add;
SynthDef(\thing, {
arg out, vol = 0.2, note = 78, cutoff = 800, bandwidth=0.75, release = 0.5;
//note.postln;
//var a = Resonz.ar((LFSaw.ar(note.midicps) * 0.5 * vol * EnvGen.kr(Env([0.9,1,0],[0.0001,release]), doneAction: 2)), cutoff, bandwidth);
var wave = (Saw.ar(note.midicps ) * 0.5 * vol * EnvGen.kr(Env([0.9,1,0],[0.0001,release]), doneAction: 2));
wave = Resonz.ar(wave, cutoff, bandwidth);
Out.ar(out,Limiter.ar(wave!2,0.8));
}).add;
SynthDef(\ping, {
arg out, note, vol=0.5, harmonics=#[1,2,3,4,5,6], release=0.5, bandwidth = 0.75, cutoff = 15000;
//var a = SinOsc.ar(LFSaw.kr(30).range(1350,350) * 0.1 * EnvGen.kr(Env.perc(releaseTime:0.2),doneAction:2));
var freq = note.midicps;
//round to the nearest fundamental
var frequencies = harmonics.collect({arg harmonic; (freq * harmonic).round(freq)}).asArray();
//or don't, and let things detune
//var frequencies = harmonics.collect({arg harmonic; (freq * harmonic)}).asArray();
var o = Klang.ar(`[frequencies, [0.9,0.1,0.1,0.1,0.1,0.1], pi.dup(6)], 1, 0);
//var o = Klang.ar(`[frequencies, [0.4,0.2,0.1,0.08,0.05,0.025], Array.fill(harmonics.size, rand(pi))], 1, 0);
//o = SinOsc.ar(note.midicps*3);
var env = EnvGen.kr(Env.perc(releaseTime:release),doneAction:2);
var wave = o * 0.8 * env * vol;
//wave = Resonz.ar(wave, cutoff, bandwidth);
wave = LPF.ar(wave,cutoff);
//wave = Mix.new([wave,saw]);
Out.ar(out,Limiter.ar(wave!2,0.9));
}).add;
z = Synth(\FreeVerb2x2, [\outbus, 0], addAction:\addToTail);
//z.set(\mix, 0.23);
//z.set(\damp, 0.4);
)
//{SinOsc.ar() * Xline.kr(1,0,2)}.play
//Excellent live-loop creator:
https://sccode.org/1-1HT
//shiftin binaural beats
(
{
var amp = 0.08;
var freq = 140;
var delta = 0.02;
//gradually detune left and right in opposite directions
var leftFreq =SinOsc.kr(0.05).range(freq * (1 + delta), freq);
var rightFreq =SinOsc.kr(0.05).range(freq, freq * (1+ delta));
[SinOsc.ar(leftFreq,0,amp),SinOsc.ar(rightFreq, 0, amp)];
}.play
)
(
{
var freq, trig, reset, seq, amp;
//change value for faster/slower (e.g. try 5, 15, 20)
amp = 0.1;
trig = Impulse.kr(10);
seq = Dswitch1(
[
//try 70 as the low note, remove high notes to start
Dseq([72, 75, 79, Drand([82,84,86, 89, 91, 94, 98])], inf)
//Dseq([72, 75, 79, Drand([82,84,86])], inf)
],
LFPulse.kr(0.2)
);
freq = Demand.kr(trig, 0, seq.midicps);
//Try LFTri, Saw, etc.
//change numerator in fraction below
SinOsc.ar(freq * 3/5 + [0,0.7]) * amp;
}.play;
)
//Fun with midi!
//Install TouchOSC on your iOS device and TouchOSC Bridge on yoru mac
// use "simple" layout
//initialize a midi client
MIDIClient.init;
//connect all the possible inputs
MIDIIn.connectAll;
//create a tone,
x = {
//allow freq & amp to be set externally once it's running
arg freq = 220, amp=0.2;
SinOsc.ar(freq) * amp;
}.play; //play it
//if we hit a midi note, display some data about it.
MIDIdef.noteOn(\noteOnFunc, {
arg vel, nn, chan, src;
[vel, nn, chan, src].postln;
});
//handle continuous control messages
MIDIdef.cc(\ccFunc, {
arg ccNum, chan;
//if it's the first slider
if(chan == 0){
//print the value
ccNum.postln;
//translate the midi note value to cycles per second and assign this to the frequency
x.set(\freq, ccNum.midicps);
};
//for the second slider, control the volume
if(chan == 1){
//print the value
ccNum.postln;
//map the linear midi slider range (from 0 to 127) to a linear volume from 0 to 0.5
x.set(\amp, LinLin.kr(ccNum,0,127,0,0.5));
};
//if it's the first red button
if (chan == 11) {
//set the volume to zero
x.set(\amp, 0);
};
//if it's the first green button
if (chan == 9 ) {
//set the volume to 0.5
x.set(\amp, 0.5);
}
//print the num & chan regardless
[ccNum, chan].postln;
});
//x.free;
//midi arps!
(
//initialize a midi client
MIDIClient.init;
//connect all the possible inputs
MIDIIn.connectAll;
//array of running arps
~arps = [];
//~cutoff= 100;
~arpySynth = {
arg freq, trig, reset, seq, amp = 0.1, cutoff = 12000, bottomNote= 72;
bottomNote = Prand([72,70,72,72]).asStream.next;
//change value for faster/slower (e.g. try 5, 15, 20)
trig = Impulse.kr(Prand([5,10,2.5,20]).asStream.next);
seq = Dswitch1(
[
//try 70 as the low note, remove high notes to start
Dseq([bottomNote, 75, 79, Drand([82,84,86, 89, 91, 94, 98])], inf)
//Dseq([72, 75, 79, Drand([82,84,86])], inf)
],
LFPulse.kr(0.2);
);
freq = Demand.kr(trig, 0, seq.midicps);
//Try LFTri, Saw, etc.
//change numerator in fraction below
//[0,0.7] provides some stereo chorusing
//BLowPass.ar(SinOsc.ar(freq * Prand([2,3,4,8]).asStream.next/5 + [0,0.7]) * amp, cutoff,0.5);
s = SinOsc.ar(freq * Prand([2,3,4,8]).asStream.next/5 + [0,0.7]) * amp;
x = LFTri.ar(freq * Prand([2,3,4,8]).asStream.next/5 + [0,0.7]).cubed * amp;
Prand([s,x]).asStream.next;
};
~deepThing = {
//TODO....SinO
};
//Drand([1,3,5,3],inf);
//~arp.set(\cutoff,12000);
//handle continuous control messages
MIDIdef.cc(\ccFunc, {
arg ccNum, chan;
//if it's the first slider
if(chan == 0){
//print the value
//translate the midi note value to cycles per second and assign this to the frequency
//~cutoff = LinLin.kr(ccNum,0,127,20,12000);
//~arps.last.set(\cutoff, ~cutoff);
};
/*
//for the second slider, control the volume
if(chan == 1){
//print the value
ccNum.postln;
//map the linear midi slider range (from 0 to 127) to a linear volume from 0 to 0.5
x.set(\amp, LinLin.kr(ccNum,0,127,0,0.5));
};
*/
//if it's the first red button
if (chan == 11 && ccNum == 0) {
//chan.postln;
//~arp.play;
~arps.size.postln;
if(~arps.size > 0) {
x = ~arps.pop;
x.free;
};
};
//if it's the first green button
if (chan == 9 && ccNum == 127) {
~arps = ~arps.add(~arpySynth.play);
~arps.size.postln;
};
//second red button, remove from the front of the list of arps
if (chan == 12 && ccNum == 0) {
//chan.postln;
//~arp.play;
if(~arps.size > 0) {
x = ~arps.removeAt(0);
x.free;
};
~arps.size.postln;
};
//print the num & chan regardless
//[ccNum, chan].postln;
});
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment