Synchronising for Rémi
This commit is contained in:
@ -9,12 +9,14 @@
|
|||||||
since: "2023",
|
since: "2023",
|
||||||
schelp: "BuboQuark",
|
schelp: "BuboQuark",
|
||||||
dependencies: [
|
dependencies: [
|
||||||
|
"https://github.com/cappelnord/BenoitLib",
|
||||||
"https://github.com/scztt/Singleton.quark",
|
"https://github.com/scztt/Singleton.quark",
|
||||||
"https://github.com/scztt/Require.quark",
|
"https://github.com/scztt/Require.quark",
|
||||||
"https://github.com/dmorgan-github/Pdv",
|
"https://github.com/dmorgan-github/Pdv",
|
||||||
"https://github.com/supercollider-quarks/Bjorklund",
|
"https://github.com/supercollider-quarks/Bjorklund",
|
||||||
"https://github.com/adcxyz/SafetyNet",
|
"https://github.com/adcxyz/SafetyNet",
|
||||||
"https://github.com/madskjeldgaard/nodeproxygui2",
|
"https://github.com/madskjeldgaard/nodeproxygui2",
|
||||||
|
"https://github.com/capital-G/sc-grids",
|
||||||
],
|
],
|
||||||
url: "https://raphaelforment.fr",
|
url: "https://raphaelforment.fr",
|
||||||
isCompatible: {Main.versionAtLeast(3, 1)},
|
isCompatible: {Main.versionAtLeast(3, 1)},
|
||||||
|
|||||||
@ -1 +0,0 @@
|
|||||||
Eu : Pbjorklund2 {}
|
|
||||||
@ -10,98 +10,70 @@
|
|||||||
^Pindex(pat, this[1], repeats)
|
^Pindex(pat, this[1], repeats)
|
||||||
}
|
}
|
||||||
|
|
||||||
findShortcuts {
|
|
||||||
arg pattern;
|
|
||||||
var short, correctedPattern;
|
|
||||||
correctedPattern = List.new();
|
|
||||||
short = Dictionary.newFrom([
|
|
||||||
// Instrument
|
|
||||||
\i, \instrument,
|
|
||||||
// Notes
|
|
||||||
\n, \note,
|
|
||||||
\mn, \midinote,
|
|
||||||
\vel, \velocity,
|
|
||||||
\deg, \degree,
|
|
||||||
\off, \timingOffset,
|
|
||||||
\o, \octave,
|
|
||||||
\f, \freq,
|
|
||||||
\det, \detune,
|
|
||||||
// Durations
|
|
||||||
\d, \dur,
|
|
||||||
\l, \legato,
|
|
||||||
// Amplitude
|
|
||||||
\p, \pan,
|
|
||||||
// Envelope
|
|
||||||
\a, \attack,
|
|
||||||
\d, \decay,
|
|
||||||
\s, \sustain,
|
|
||||||
\r, \release,
|
|
||||||
// Filter control
|
|
||||||
\r, \resonance,
|
|
||||||
\ff, \ffreq,
|
|
||||||
// Modulation
|
|
||||||
\m, \mod,
|
|
||||||
\mo, \midout,
|
|
||||||
\c, \midichan,
|
|
||||||
\st, \stretch,
|
|
||||||
\rt, \root,
|
|
||||||
\scl, \scale,
|
|
||||||
]);
|
|
||||||
|
|
||||||
// shortcuts are turned into regular keys;
|
|
||||||
pattern.do({| element |
|
|
||||||
if (short.includesKey(element),
|
|
||||||
{correctedPattern.add(short[element])},
|
|
||||||
{correctedPattern.add(element)}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
^correctedPattern;
|
|
||||||
}
|
|
||||||
|
|
||||||
pat {
|
pat {
|
||||||
arg quant=4, fade=0.05;
|
arg quant=4, fade=0.05;
|
||||||
var proxyName = this[0];
|
var proxyName = this[0];
|
||||||
var newArray = this[1..] ++ [\type, \buboEvent];
|
var newArray = this[1..] ++ [\type, \buboEvent];
|
||||||
currentEnvironment.at(proxyName.asSymbol).quant_(quant);
|
currentEnvironment.at(proxyName.asSymbol).quant_(quant);
|
||||||
currentEnvironment.at(proxyName.asSymbol).fadeTime = fade;
|
currentEnvironment.at(proxyName.asSymbol).fadeTime = fade;
|
||||||
currentEnvironment.at(proxyName.asSymbol)[0] = Pbind(*(this.findShortcuts(newArray)));
|
currentEnvironment.at(proxyName.asSymbol)[0] = Pbind(*(EventShortener.findShortcuts(newArray)));
|
||||||
^currentEnvironment.at(proxyName.asSymbol);
|
^currentEnvironment.at(proxyName.asSymbol);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pwrap {
|
||||||
|
arg maxIndex, startIndex=0, repeats=inf;
|
||||||
|
^PwrapSeq(this, maxIndex, startIndex, repeats)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
p {
|
p {
|
||||||
^Pbind(*(this.findShortcuts(this)))
|
^Pbind(*(Eventshortener.findShortcuts(this)))
|
||||||
}
|
}
|
||||||
|
|
||||||
euclid {
|
eu {
|
||||||
arg repeats=inf;
|
arg repeats=inf;
|
||||||
^Pbjorklund2(this[0], this[1], repeats);
|
var divisor = 1;
|
||||||
|
if (this[3] != nil, { divisor = this[3] });
|
||||||
|
^Pbjorklund2(this[0], this[1], repeats, this[2]) / divisor;
|
||||||
}
|
}
|
||||||
|
|
||||||
pseq { arg repeats=inf, offset=0;
|
pseq {
|
||||||
^Pseq(this, repeats, offset);
|
arg repeats=inf;
|
||||||
|
^Pseq(this, repeats);
|
||||||
}
|
}
|
||||||
|
|
||||||
pshuf { arg repeats=1;
|
pshuf {
|
||||||
|
arg repeats=1;
|
||||||
^Pshuf(this, repeats);
|
^Pshuf(this, repeats);
|
||||||
}
|
}
|
||||||
|
|
||||||
prand { arg repeats=inf;
|
prand {
|
||||||
|
arg repeats=inf;
|
||||||
^Prand(this, repeats);
|
^Prand(this, repeats);
|
||||||
}
|
}
|
||||||
|
|
||||||
pxrand { arg repeats=inf;
|
pxrand {
|
||||||
|
arg repeats=inf;
|
||||||
^Pxrand(this, repeats);
|
^Pxrand(this, repeats);
|
||||||
}
|
}
|
||||||
|
|
||||||
pwrand { arg weights, repeats=1;
|
pwrand {
|
||||||
|
arg weights, repeats=1;
|
||||||
^Pwrand(this, weights.normalizeSum, repeats);
|
^Pwrand(this, weights.normalizeSum, repeats);
|
||||||
}
|
}
|
||||||
|
|
||||||
pwhite { arg repeats=inf;
|
pwhite {
|
||||||
|
arg repeats=inf;
|
||||||
^Pwhite(this[0], this[1], repeats);
|
^Pwhite(this[0], this[1], repeats);
|
||||||
}
|
}
|
||||||
|
|
||||||
pseries { arg repeats=inf;
|
pseries {
|
||||||
|
arg repeats=inf;
|
||||||
^Pseries(this[0], this[1], repeats);
|
^Pseries(this[0], this[1], repeats);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pbrown {
|
||||||
|
arg repeats=inf;
|
||||||
|
^Pbrown(this[0], this[1], this[2], repeats);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,13 +8,7 @@ Boot {
|
|||||||
*new {
|
*new {
|
||||||
arg configPath, samplePath, serverOptions;
|
arg configPath, samplePath, serverOptions;
|
||||||
var p; var c; var t; var s;
|
var p; var c; var t; var s;
|
||||||
var banner = "┳┓ ┓ ┳┓\n"
|
BuboUtils.fancyPrint(BuboUtils.banner, 40);
|
||||||
"┣┫┓┏┣┓┏┓ ┣┫┏┓┏┓╋\n"
|
|
||||||
"┻┛┗┻┗┛┗┛ ┻┛┗┛┗┛┗";
|
|
||||||
var ready = "┓ ┳┓┏┏┓ ┏┓┏┓┳┓┏┓ ┳┓┏┓┏┓┳┓┓┏\n"
|
|
||||||
"┃ ┃┃┃┣ ┃ ┃┃┃┃┣ ┣┫┣ ┣┫┃┃┗┫\n"
|
|
||||||
"┗┛┻┗┛┗┛ ┗┛┗┛┻┛┗┛ ┛┗┗┛┛┗┻┛┗┛";
|
|
||||||
this.fancyPrint(banner, 40);
|
|
||||||
|
|
||||||
if (serverOptions == nil,
|
if (serverOptions == nil,
|
||||||
{
|
{
|
||||||
@ -55,29 +49,18 @@ Boot {
|
|||||||
Server.default.waitForBoot({
|
Server.default.waitForBoot({
|
||||||
"-> Loading config from: %".format(configPath ? (this.localPath +/+ "Startup.scd")).postln;
|
"-> Loading config from: %".format(configPath ? (this.localPath +/+ "Startup.scd")).postln;
|
||||||
(configPath ? (this.localPath +/+ "Startup.scd")).load;
|
(configPath ? (this.localPath +/+ "Startup.scd")).load;
|
||||||
Safety.setLimit(0.8);
|
Safety.all;
|
||||||
this.fancyPrint(ready, 40);
|
Safety(s).defName = \safeLimit;
|
||||||
|
Safety.setLimit(1);
|
||||||
|
BuboUtils.fancyPrint(BuboUtils.ready, 40);
|
||||||
this.installServerTreeBehavior();
|
this.installServerTreeBehavior();
|
||||||
this.clock.enableMeterSync();
|
this.clock.enableMeterSync();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
*fancyPrint {
|
|
||||||
arg message, length;
|
|
||||||
var separator= length.collect({
|
|
||||||
arg index;
|
|
||||||
if (index % 2 == 0, "=", "-")
|
|
||||||
});
|
|
||||||
separator = separator.join("");
|
|
||||||
[separator, message, separator].do({
|
|
||||||
arg each;
|
|
||||||
each.postln;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
*installServerTreeBehavior {
|
*installServerTreeBehavior {
|
||||||
CmdPeriod.add({
|
CmdPeriod.add({
|
||||||
this.fancyPrint("\nBubo SuperCollider Session\nTempo: % | Peers: %\nCPU: % | Peak: %\n".format(
|
BuboUtils.fancyPrint("\nBubo SuperCollider Session\nTempo: % | Peers: %\nCPU: % | Peak: %\n".format(
|
||||||
this.clock.tempo * 60, this.clock.numPeers,
|
this.clock.tempo * 60, this.clock.numPeers,
|
||||||
Server.default.avgCPU.round(2),
|
Server.default.avgCPU.round(2),
|
||||||
Server.default.peakCPU.round(2)), 40)
|
Server.default.peakCPU.round(2)), 40)
|
||||||
@ -88,6 +71,7 @@ Boot {
|
|||||||
{ ~buf = Bank(~sp)[~nb % Bank(~sp).buffers.size]; }
|
{ ~buf = Bank(~sp)[~nb % Bank(~sp).buffers.size]; }
|
||||||
);
|
);
|
||||||
if (~nb == nil) {~nb = 0};
|
if (~nb == nil) {~nb = 0};
|
||||||
|
if (~sp == nil) {~sp = 'default'};
|
||||||
~type = \note;
|
~type = \note;
|
||||||
currentEnvironment.play;
|
currentEnvironment.play;
|
||||||
});
|
});
|
||||||
|
|||||||
16
Classes/BuboEnv.sc
Normal file
16
Classes/BuboEnv.sc
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
+ Env {
|
||||||
|
|
||||||
|
*rand {
|
||||||
|
arg numSegs=8, dur=1, bipolar=true;
|
||||||
|
var env, levels, times, curves, minLevel;
|
||||||
|
levels = {rrand(-1.0, 1.0)}!numSegs+1;
|
||||||
|
minLevel = bipolar.asInteger.neg;
|
||||||
|
levels = levels.normalize(minLevel, 1);
|
||||||
|
times = {exprand(1,10)}!numSegs;
|
||||||
|
times = times.normalizeSum * dur;
|
||||||
|
curves = {rrand(-4.0,4.0)}!numSegs;
|
||||||
|
env = this.new(levels, times, curves);
|
||||||
|
^env;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -1,5 +1,7 @@
|
|||||||
+ NodeProxy {
|
+ NodeProxy {
|
||||||
|
|
||||||
|
/* Simple FX chain management */
|
||||||
|
|
||||||
fx {
|
fx {
|
||||||
arg number=1, wet=1, function = {|in| in};
|
arg number=1, wet=1, function = {|in| in};
|
||||||
this[number] = \filter -> function;
|
this[number] = \filter -> function;
|
||||||
@ -34,4 +36,54 @@
|
|||||||
this.set(("wet" ++ number).asSymbol, wet);
|
this.set(("wet" ++ number).asSymbol, wet);
|
||||||
^this;
|
^this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Player-like syntax sugar */
|
||||||
|
=> {
|
||||||
|
arg pattern;
|
||||||
|
pattern = EventShortener.findShortcuts(pattern);
|
||||||
|
pattern = pattern ++ [\type, \buboEvent];
|
||||||
|
this[0] = Pbind(*pattern);
|
||||||
|
this.quant = 4; this.fadeTime = 0.01;
|
||||||
|
^this
|
||||||
|
}
|
||||||
|
|
||||||
|
/* FIX: Completely broken. What is the event type
|
||||||
|
* BuboEvent should fall back to after tweaking
|
||||||
|
* the pattern to my liking?
|
||||||
|
*/
|
||||||
|
-> {
|
||||||
|
arg pattern;
|
||||||
|
pattern = EventShortener.findShortcuts(pattern);
|
||||||
|
// pattern = pattern ++ [\type, \buboMonoEvent];
|
||||||
|
this[0] = Pmono(*pattern);
|
||||||
|
this.quant = 4;
|
||||||
|
this.fadeTime = 0.01;
|
||||||
|
}
|
||||||
|
|
||||||
|
f {
|
||||||
|
arg value;
|
||||||
|
this.fadeTime = value;
|
||||||
|
^this
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
arg quant, fade;
|
||||||
|
this.quant = quant;
|
||||||
|
this.fadeTime = fade;
|
||||||
|
this.play(fadeTime: fade);
|
||||||
|
^this
|
||||||
|
}
|
||||||
|
|
||||||
|
s {
|
||||||
|
arg duration;
|
||||||
|
this.stop(fadeTime: duration)
|
||||||
|
^this
|
||||||
|
}
|
||||||
|
|
||||||
|
/ {
|
||||||
|
arg pattern;
|
||||||
|
this.stop(1);
|
||||||
|
^this
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
30
Classes/BuboUtils.sc
Normal file
30
Classes/BuboUtils.sc
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
BuboUtils {
|
||||||
|
|
||||||
|
*banner {
|
||||||
|
var banner = "┳┓ ┓ ┳┓\n"
|
||||||
|
"┣┫┓┏┣┓┏┓ ┣┫┏┓┏┓╋\n"
|
||||||
|
"┻┛┗┻┗┛┗┛ ┻┛┗┛┗┛┗";
|
||||||
|
^banner
|
||||||
|
}
|
||||||
|
|
||||||
|
*ready {
|
||||||
|
var ready = "┓ ┳┓┏┏┓ ┏┓┏┓┳┓┏┓ ┳┓┏┓┏┓┳┓┓┏\n"
|
||||||
|
"┃ ┃┃┃┣ ┃ ┃┃┃┃┣ ┣┫┣ ┣┫┃┃┗┫\n"
|
||||||
|
"┗┛┻┗┛┗┛ ┗┛┗┛┻┛┗┛ ┛┗┗┛┛┗┻┛┗┛";
|
||||||
|
^ready
|
||||||
|
}
|
||||||
|
|
||||||
|
*fancyPrint {
|
||||||
|
arg message, length;
|
||||||
|
var separator= length.collect({
|
||||||
|
arg index;
|
||||||
|
if (index % 2 == 0, "=", "-")
|
||||||
|
});
|
||||||
|
separator = separator.join("");
|
||||||
|
[separator, message, separator].do({
|
||||||
|
arg each;
|
||||||
|
each.postln;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ -3,4 +3,4 @@ p = currentEnvironment;
|
|||||||
c = currentEnvironment.clock;
|
c = currentEnvironment.clock;
|
||||||
"Loading SynthDefs".postln;
|
"Loading SynthDefs".postln;
|
||||||
"Synthdefs.scd".loadRelative;
|
"Synthdefs.scd".loadRelative;
|
||||||
// m = MIDIOut.newByName("MIDI", "Bus 1");
|
m = MIDIControl();
|
||||||
|
|||||||
@ -16,124 +16,86 @@ f.vardel = {
|
|||||||
* This is the sampler used for 90% of sampling duties.
|
* This is the sampler used for 90% of sampling duties.
|
||||||
*/
|
*/
|
||||||
(
|
(
|
||||||
z = SynthDef.new(\s, {
|
z = SynthDef.new(\player, {
|
||||||
arg buf, out=0, freq=440, rate=1, amp=1, begin=0, end=1, pan=0, attack=0.01, release=1, loop=0;
|
arg buf;
|
||||||
var sig;
|
var sig, env = EnvGen.ar(
|
||||||
var env = EnvGen.ar(Env.perc(attack, release, doneAction: 2));
|
Env.perc(
|
||||||
var startPos = begin * BufFrames.kr(buf);
|
\attack.kr(0.01),
|
||||||
var endPos = end * BufFrames.kr(buf); // TODO: unused
|
\release.kr(1),
|
||||||
|
doneAction: 2)
|
||||||
|
);
|
||||||
|
var startPos = \begin.kr(0) * BufFrames.kr(buf);
|
||||||
|
var endPos = \end.kr(1) * BufFrames.kr(buf); // TODO: unused
|
||||||
sig = PlayBuf.ar(
|
sig = PlayBuf.ar(
|
||||||
numChannels: 1,
|
numChannels: 1,
|
||||||
bufnum: buf,
|
bufnum: buf,
|
||||||
rate:BufRateScale.kr(buf) * (rate * freq / 60.midicps),
|
rate:BufRateScale.kr(buf) * (\rate.kr(1) * \freq.kr(400) / 60.midicps),
|
||||||
trigger: 1, startPos:startPos,
|
trigger: 1, startPos:startPos,
|
||||||
loop:loop, doneAction: 2);
|
loop:\loop.kr(0), doneAction: 2);
|
||||||
sig = sig * amp;
|
sig = sig * \amp.kr(-6.dbamp);
|
||||||
sig = Pan2.ar(sig * env, pan);
|
sig = Pan2.ar(sig * env, \pan.kr(0));
|
||||||
OffsetOut.ar(out, sig)
|
OffsetOut.ar(\out.kr(0), sig)
|
||||||
}).add;
|
}).add;
|
||||||
d.s = z;
|
d.player = z;
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Stereo variant
|
||||||
|
*/
|
||||||
|
(
|
||||||
|
z = SynthDef.new(\splayer, {
|
||||||
|
arg buf;
|
||||||
|
var sig, env = EnvGen.ar(
|
||||||
|
Env.perc(
|
||||||
|
\attack.kr(0.01),
|
||||||
|
\release.kr(1),
|
||||||
|
doneAction: 2)
|
||||||
|
);
|
||||||
|
var startPos = \begin.kr(0) * BufFrames.kr(buf);
|
||||||
|
var endPos = \end.kr(1) * BufFrames.kr(buf); // TODO: unused
|
||||||
|
sig = PlayBuf.ar(
|
||||||
|
numChannels: 2,
|
||||||
|
bufnum: buf,
|
||||||
|
rate:BufRateScale.kr(buf) * (\rate.kr(1) * \freq.kr(400) / 60.midicps),
|
||||||
|
trigger: 1, startPos:startPos,
|
||||||
|
loop:\loop.kr(0), doneAction: 2);
|
||||||
|
sig = sig * \amp.kr(-6.dbamp);
|
||||||
|
sig = Pan2.ar(sig * env, \pan.kr(0));
|
||||||
|
OffsetOut.ar(\out.kr(0), sig)
|
||||||
|
}).add;
|
||||||
|
d.splayer = z;
|
||||||
);
|
);
|
||||||
|
|
||||||
(
|
(
|
||||||
z = SynthDef(\sinfb, {
|
z = SynthDef(\sinfb, {
|
||||||
arg freq = 440, atk = 0.01, sus = 0, rel = 1, fb = 0, amp = 0.3, out = 0, pan=0;
|
|
||||||
var sig, env;
|
var sig, env;
|
||||||
env = EnvGen.ar(Env.linen(atk,sus,rel),1,1,0,1,2);
|
env = EnvGen.ar(
|
||||||
sig = SinOscFB.ar(freq,fb,1);
|
Env.linen(
|
||||||
sig = sig*env;
|
\attack.kr(0.01),
|
||||||
Out.ar(out,Pan2.ar(sig,pan,amp));
|
\sustain.kr(0),
|
||||||
|
\release.kr(1)
|
||||||
|
),1,1,0,1,2);
|
||||||
|
sig = SinOscFB.ar(
|
||||||
|
\freq.kr(400),
|
||||||
|
\fb.kr(0),
|
||||||
|
1
|
||||||
|
);
|
||||||
|
sig = sig * env;
|
||||||
|
OffsetOut.ar(\out.kr(0), Pan2.ar(sig, \pan.kr(0), \amp.kr(-6.dbamp)));
|
||||||
}).add;
|
}).add;
|
||||||
d.sinfb = z;
|
d.sinfb = z;
|
||||||
);
|
);
|
||||||
|
|
||||||
(
|
(
|
||||||
z = SynthDef(\kick2, {
|
z = SynthDef(\omi, {
|
||||||
var snd;
|
var envLength = \sustain.kr(1) * (\end.kr(1) - \begin.kr(0)) / \speed.kr(1);
|
||||||
snd = DC.ar(0);
|
var line = Line.ar(\begin.kr, \end.kr, envLength, doneAction: Done.freeSelf);
|
||||||
snd = snd + (HPF.ar(Hasher.ar(Sweep.ar), 1320) * Env.perc(0.003, 0.03).ar * 0.5);
|
|
||||||
snd = snd + (SinOsc.ar(XLine.ar(750, 161, 0.02)) * Env.perc(0.0005, 0.02).ar);
|
|
||||||
snd = snd + (SinOsc.ar(XLine.ar(167, 52, 0.04)) * Env.perc(0.0005, 0.3).ar(2));
|
|
||||||
snd = snd.tanh;
|
|
||||||
Out.ar(\out.kr(0), Pan2.ar(snd, \pan.kr(0), \amp.kr(0.9)));
|
|
||||||
}).add;
|
|
||||||
d.kick2 = z;
|
|
||||||
);
|
|
||||||
|
|
||||||
(
|
|
||||||
z = SynthDef(\kick3, {
|
|
||||||
var snd;
|
|
||||||
snd = DC.ar(0);
|
|
||||||
snd = snd + (SinOsc.ar(XLine.ar(1500, 800, 0.01)) * Env.perc(0.0005, 0.01, curve: \lin).ar);
|
|
||||||
snd = snd + (BPF.ar(Impulse.ar(0) * SampleRate.ir / 48000, 6100, 1.0) * 3.dbamp);
|
|
||||||
snd = snd + (BPF.ar(Hasher.ar(Sweep.ar), 300, 0.9) * Env.perc(0.001, 0.02).ar);
|
|
||||||
snd = snd + (SinOsc.ar(XLine.ar(472, 60, 0.045)) * Env.perc(0.0001, 0.3, curve: \lin).delay(0.005).ar(2));
|
|
||||||
snd = snd.tanh;
|
|
||||||
Out.ar(\out.kr(0), Pan2.ar(snd, \pan.kr(0), \amp.kr(0.1)));
|
|
||||||
}).add;
|
|
||||||
d.kick3 = z;
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
(
|
|
||||||
z = SynthDef("snare", {arg amp = 0.1, freq = 100, att = 0.01, rel = 0.2, ffreq = 2000, pan = 0;
|
|
||||||
var env, snd1, snd2, sum;
|
|
||||||
env = Env.perc(att, rel, amp).kr;
|
|
||||||
snd1 = HPF.ar(
|
|
||||||
in: WhiteNoise.ar,
|
|
||||||
freq: ffreq
|
|
||||||
);
|
|
||||||
snd2 = SinOsc.ar(freq: freq);
|
|
||||||
sum = snd1 + snd2;
|
|
||||||
sum = sum * env;
|
|
||||||
Out.ar(0, Pan2.ar(sum, pan));
|
|
||||||
DetectSilence.ar(sum, doneAction: 2);
|
|
||||||
}).add;
|
|
||||||
d.snare = z;
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
(
|
|
||||||
z = SynthDef("hihat", {arg amp = 0.5, att = 0.01, rel = 0.2, ffreq = 6000, pan = 0;
|
|
||||||
var env, snd;
|
|
||||||
env = Env.perc(
|
|
||||||
attackTime: att,
|
|
||||||
releaseTime: rel,
|
|
||||||
level: amp*1.2
|
|
||||||
).kr;
|
|
||||||
snd = WhiteNoise.ar;
|
|
||||||
snd = HPF.ar(in: snd, freq: ffreq);
|
|
||||||
snd = snd * env;
|
|
||||||
Out.ar(0, Pan2.ar(snd, pan));
|
|
||||||
DetectSilence.ar(snd, doneAction: 2);
|
|
||||||
}).add;
|
|
||||||
d.hihat = z;
|
|
||||||
);
|
|
||||||
|
|
||||||
(
|
|
||||||
z = SynthDef(\kick1, {
|
|
||||||
var snd;
|
|
||||||
snd = DC.ar(0);
|
|
||||||
snd = snd + (SinOsc.ar(XLine.ar(800, 400, 0.01)) * Env.perc(0.0005, 0.01).ar);
|
|
||||||
snd = snd + (BPF.ar(Hasher.ar(Sweep.ar), XLine.ar(800, 100, 0.01), 0.6) * Env.perc(0.001, 0.02).delay(0.001).ar);
|
|
||||||
snd = snd + (SinOsc.ar(XLine.ar(172, 50, 0.01)) * Env.perc(0.0001, 0.3, 1, \lin).delay(0.005).ar(2));
|
|
||||||
snd = snd.tanh;
|
|
||||||
Out.ar(\out.kr(0), Pan2.ar(snd, \pan.kr(0), \amp.kr(0.1)));
|
|
||||||
}).add;
|
|
||||||
d.kick1 = z;
|
|
||||||
);
|
|
||||||
|
|
||||||
(
|
|
||||||
z = SynthDef(\omi, {|out=0,freq=440,amp=0.5,sustain=1,pan=0,begin=0,end=1,speed=1,accelerate=0|
|
|
||||||
var envLength = sustain*(end-begin)/speed;
|
|
||||||
var line = Line.ar(begin, end, envLength, doneAction: Done.freeSelf);
|
|
||||||
var env = Env.asr;
|
var env = Env.asr;
|
||||||
var volume = IEnvGen.ar(env, line) * amp;
|
var volume = IEnvGen.ar(env, line) * \amp.kr(-6.dbamp);
|
||||||
var sig;
|
var sig;
|
||||||
|
sig = MiOmi.ar(pit: \freq.kr(400).cpsmidi);
|
||||||
freq = max(0, freq * speed * (1 + (accelerate * line)));
|
OffsetOut.ar(\out.kr(0), Pan2.ar(sig * volume, \pan.kr(0)));
|
||||||
sig = MiOmi.ar(pit: freq.cpsmidi);
|
|
||||||
Out.ar(out, Pan2.ar(sig * volume, pan));
|
|
||||||
}).add;
|
}).add;
|
||||||
d.omi = z;
|
d.omi = z;
|
||||||
);
|
);
|
||||||
@ -141,52 +103,33 @@ f.vardel = {
|
|||||||
|
|
||||||
(
|
(
|
||||||
[
|
[
|
||||||
'analog', 'waveshape',
|
'Panalog', 'Pwaveshape', 'Pfm', 'Pgrain',
|
||||||
'fm', 'grain',
|
'Padditive', 'Pwavetable', 'Pchord', 'Pspeech',
|
||||||
'additive', 'wavetable',
|
'Pswarm', 'Pnoise', 'Pparticle', 'Pstring',
|
||||||
'chord', 'speech',
|
'Pmodal', 'Pbass', 'Psnare', 'Phat'
|
||||||
'swarm', 'noise',
|
|
||||||
'particle', 'string',
|
|
||||||
'modal', 'bass',
|
|
||||||
'snare', 'hat'
|
|
||||||
].do({arg name, index;
|
].do({arg name, index;
|
||||||
var synth;
|
var synth;
|
||||||
synth = SynthDef(name, {
|
synth = SynthDef(name, {
|
||||||
arg out,
|
var env = EnvGen.ar(
|
||||||
freq=440,
|
Env.perc(
|
||||||
attack=0.01,
|
\attack.kr(0.01),
|
||||||
decay=0.3,
|
\release.kr(1)
|
||||||
sustain=0.5,
|
), doneAction: Done.freeSelf
|
||||||
release=1.0,
|
|
||||||
pan=0,
|
|
||||||
speed=1,
|
|
||||||
accelerate=0,
|
|
||||||
amp=1,
|
|
||||||
alt=1,
|
|
||||||
timbre=0.5,
|
|
||||||
harm=0.5,
|
|
||||||
morph=0.5,
|
|
||||||
level=1,
|
|
||||||
gate=1,
|
|
||||||
lpgdecay=0,
|
|
||||||
lpgcolour=0,
|
|
||||||
mode=0;
|
|
||||||
var env = EnvGen.ar(Env.adsr(attack, decay, sustain, release, curve: [2, -4, -4]), doneAction: Done.freeSelf, gate: gate);
|
|
||||||
var sig;
|
|
||||||
freq = max(0, freq * speed * (1 + (accelerate * env)));
|
|
||||||
sig = MiPlaits.ar(
|
|
||||||
pitch: freq.cpsmidi,
|
|
||||||
timbre: timbre,
|
|
||||||
harm: harm,
|
|
||||||
engine: index,
|
|
||||||
morph: morph,
|
|
||||||
level: level,
|
|
||||||
decay: lpgdecay,
|
|
||||||
lpg_colour: lpgcolour,
|
|
||||||
);
|
);
|
||||||
sig = Pan2.ar(sig[0], pan);
|
var sig;
|
||||||
sig = sig * env * amp;
|
sig = MiPlaits.ar(
|
||||||
OffsetOut.ar(out, sig);
|
pitch: \freq.kr(400).cpsmidi,
|
||||||
|
timbre: \timbre.kr(0),
|
||||||
|
harm: \harm.kr(0),
|
||||||
|
engine: index,
|
||||||
|
morph: \morph.kr(0),
|
||||||
|
level: \level.kr(1),
|
||||||
|
decay: \lpgdecay.kr(0),
|
||||||
|
lpg_colour: \lpgcolour.kr(0),
|
||||||
|
);
|
||||||
|
sig = Pan2.ar(sig[0], \pan.kr(0));
|
||||||
|
sig = sig * env * \amp.kr(-6.dbamp);
|
||||||
|
OffsetOut.ar(\out.kr(0), sig);
|
||||||
}).add;
|
}).add;
|
||||||
d.put(name, synth);
|
d.put(name, synth);
|
||||||
});
|
});
|
||||||
@ -194,68 +137,91 @@ f.vardel = {
|
|||||||
|
|
||||||
|
|
||||||
(
|
(
|
||||||
['csaw', 'morph', 'saw_square', 'sine_triangle',
|
[
|
||||||
'buzz', 'square_sub', 'saw_sub', 'square_sync',
|
'Bcsaw',
|
||||||
'saw_sync', 'triple_saw', 'triple_square',
|
'Bmorph',
|
||||||
'triple_triangle', 'triple_sine', 'triple_ring_mod',
|
'Bsaw_square',
|
||||||
'saw_swarm', 'saw_comb', 'toy', 'filter_lp',
|
'Bsine_triangle',
|
||||||
'filter_pk', 'filter_bp', 'filter_hp', 'vosim',
|
'Bbuzz',
|
||||||
'vowel', 'vowel_fof', 'harmonics', 'bfm', 'feedback_fm',
|
'Bsquare_sub',
|
||||||
'chaotic_feedback_fm', 'plucked', 'bowed', 'blown', 'fluted',
|
'Bsaw_sub',
|
||||||
'struck_bell', 'struck_drum', 'bkick', 'cymbal', 'bsnare',
|
'Bsquare_sync',
|
||||||
'bwavetable', 'wave_map', 'wave_line', 'wave_paraphonic',
|
'Bsaw_sync',
|
||||||
'filtered_noise', 'twin_peaks_noise', 'clocked_noise',
|
'Bt_saw',
|
||||||
'granular_cloud', 'particle_noise', 'digital_modulation',
|
'Bt_square',
|
||||||
'question_mark'].do({
|
'Bt_triangle',
|
||||||
|
'Bt_sine',
|
||||||
|
'Bt_ring_mod',
|
||||||
|
'Bsaw_swarm',
|
||||||
|
'Bsaw_comb',
|
||||||
|
'Btoy',
|
||||||
|
'Bfilter_lp',
|
||||||
|
'Bfilter_pk',
|
||||||
|
'Bfilter_bp',
|
||||||
|
'Bfilter_hp',
|
||||||
|
'Bvosim',
|
||||||
|
'Bvowel',
|
||||||
|
'Bvowel_fof',
|
||||||
|
'Bharmonics',
|
||||||
|
'Bbfm',
|
||||||
|
'Bfeedback_fm',
|
||||||
|
'Bchaotic_feedback_fm',
|
||||||
|
'Bplucked',
|
||||||
|
'Bbowed',
|
||||||
|
'Bblown',
|
||||||
|
'Bfluted',
|
||||||
|
'Bstruck_bell',
|
||||||
|
'Bstruck_drum',
|
||||||
|
'Bbkick',
|
||||||
|
'Bcymbal',
|
||||||
|
'Bbsnare',
|
||||||
|
'Bbwavetable',
|
||||||
|
'Bwave_map',
|
||||||
|
'Bwave_line',
|
||||||
|
'Bwave_paraphonic',
|
||||||
|
'Bfiltered_noise',
|
||||||
|
'Btwin_peaks_noise',
|
||||||
|
'Bclocked_noise',
|
||||||
|
'Bgranular_cloud',
|
||||||
|
'Bparticle_noise',
|
||||||
|
'Bdigital_modulation',
|
||||||
|
'Bquestion_mark'].do({
|
||||||
arg name, index;
|
arg name, index;
|
||||||
var synth;
|
var synth;
|
||||||
synth = SynthDef(name, {
|
synth = SynthDef(name, {
|
||||||
arg out,
|
|
||||||
freq=440,
|
|
||||||
amp=1,
|
|
||||||
attack=0.01,
|
|
||||||
decay=0.3,
|
|
||||||
sustain=0.5,
|
|
||||||
release=1.0,
|
|
||||||
pan=0,begin=0,
|
|
||||||
end=1,speed=1,
|
|
||||||
accelerate=0,
|
|
||||||
timbre=0.5,
|
|
||||||
color=0.5,
|
|
||||||
ws=0,bits=0,
|
|
||||||
resamp=0,
|
|
||||||
decim=32,
|
|
||||||
gate=1;
|
|
||||||
var sig;
|
var sig;
|
||||||
var env = EnvGen.ar(Env.adsr(attack, decay, sustain, release, curve: [2, -4, -4]), doneAction: Done.freeSelf, gate: gate);
|
var env = EnvGen.ar(Env.perc(\attack.kr(0.01), \release.kr(1)), doneAction: Done.freeSelf);
|
||||||
freq = max(0, freq * speed * (1 + (accelerate * env)));
|
var freq = \freq.kr;
|
||||||
sig = MiBraids.ar(pitch: freq.cpsmidi, timbre: timbre, resamp: 0, decim: decim, color: color, model: index, ws: ws, bits:bits);
|
sig = MiBraids.ar(
|
||||||
Out.ar(out, Pan2.ar(sig * env * amp, pan));
|
pitch: freq.cpsmidi,
|
||||||
|
timbre: \timbre.kr(0),
|
||||||
|
color: \color.kr(0),
|
||||||
|
resamp: 0,
|
||||||
|
decim: \decim.kr(32),
|
||||||
|
model: index,
|
||||||
|
ws: \ws.kr(0),
|
||||||
|
bits: \bits.kr(0)
|
||||||
|
);
|
||||||
|
OffsetOut.ar(\out.kr(0), Pan2.ar(sig * env * \amp.kr(-6.dbamp), \pan.kr(0)));
|
||||||
}).add;
|
}).add;
|
||||||
d.put(name, synth);
|
d.put(name, synth);
|
||||||
});
|
});
|
||||||
);
|
);
|
||||||
|
|
||||||
(
|
(
|
||||||
z = SynthDef(\tides, {|out=0,freq=440,amp=0.5,sustain=1,pan=0,begin=0,end=1,speed=1,accelerate=0,tidesshape=0.5,slope=0.5,tidessmooth=0.5,shift=0.5,mode=2|
|
z = SynthDef(\tides, {
|
||||||
var envLength = sustain*(end-begin)/speed;
|
var env = Env.perc(\attack.kr(0.01), \release.kr(1)).ar(2);
|
||||||
var line = Line.ar(begin, end, envLength, doneAction: Done.freeSelf);
|
var sig = MiTides.ar(
|
||||||
var env = Env.asr;
|
freq: \freq.kr(400),
|
||||||
var volume = IEnvGen.ar(env, line) * amp;
|
shape: \shape.kr(0),
|
||||||
var sig;
|
slope: \slope.kr(0),
|
||||||
|
smooth: \smooth.kr(0),
|
||||||
freq = max(0, freq * speed * (1 + (accelerate * line)));
|
shift: \shift.kr(0),
|
||||||
sig = MiTides.ar(
|
output_mode: \mode.kr(2),
|
||||||
freq: freq,
|
|
||||||
shape: tidesshape,
|
|
||||||
slope: slope,
|
|
||||||
smooth: tidessmooth,
|
|
||||||
shift: shift,
|
|
||||||
output_mode: mode,
|
|
||||||
ramp_mode: 1,
|
ramp_mode: 1,
|
||||||
rate: 1
|
rate: 1
|
||||||
);
|
);
|
||||||
Out.ar(out, Pan2.ar(sig * volume, pan));
|
OffsetOut.ar(\out.kr(0), Pan2.ar(sig * env * \amp.kr(-6.dbamp), \pan.kr(0)));
|
||||||
}).add;
|
}).add;
|
||||||
d.tides = z;
|
d.tides = z;
|
||||||
);
|
);
|
||||||
|
|||||||
135
Classes/Controllers/MIDIMix.sc
Normal file
135
Classes/Controllers/MIDIMix.sc
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
ControllerValue {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A ControllerValue represents a MIDI Controller value.
|
||||||
|
* It has a minimum and maximum value, and a curve. This
|
||||||
|
* is used to convert from the MIDI value to a value that
|
||||||
|
* is considered usable by the user.
|
||||||
|
*
|
||||||
|
* The curve is similar to the one used by the Env object.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var <>min = 0;
|
||||||
|
var <>max = 1;
|
||||||
|
var <>curve = 0;
|
||||||
|
var <>currentValue;
|
||||||
|
var <>bipolar = false;
|
||||||
|
|
||||||
|
*new {
|
||||||
|
arg min, max, curve;
|
||||||
|
^super.new.init()
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
this.min = min;
|
||||||
|
this.max = max;
|
||||||
|
this.curve = curve;
|
||||||
|
this.currentValue = Bus.control;
|
||||||
|
this.bipolar = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
set {
|
||||||
|
arg value;
|
||||||
|
// If bipolar is true, then the value must go from -1 to 1
|
||||||
|
var conversion = value.lincurve(
|
||||||
|
inMin: 0,
|
||||||
|
inMax: 127,
|
||||||
|
outMin: this.min.neg,
|
||||||
|
outMax: this.max,
|
||||||
|
curve: this.curve
|
||||||
|
);
|
||||||
|
this.currentValue.set(conversion);
|
||||||
|
^this.currentValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
MIDIControl {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is my personal MIDI controller interface. I am using a
|
||||||
|
* MIDIMix. It has 8 faders, 24 knobs, and 16 buttons. I am only
|
||||||
|
* using the knobs and faders. Two buttons are used to change "bank"
|
||||||
|
* (increments the CC number value).
|
||||||
|
*/
|
||||||
|
|
||||||
|
var <>currentBank = 0;
|
||||||
|
var <>values;
|
||||||
|
|
||||||
|
*new {
|
||||||
|
^super.new.init()
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
this.values = IdentityDictionary.new();
|
||||||
|
this.connect(); this.installCallbacks();
|
||||||
|
}
|
||||||
|
|
||||||
|
getInit {
|
||||||
|
arg number;
|
||||||
|
if (this.values[number] == nil) {
|
||||||
|
this.values[number] = ControllerValue.new(
|
||||||
|
min: 0, max: 127, curve: 0
|
||||||
|
);
|
||||||
|
^this.values[number]
|
||||||
|
} {
|
||||||
|
^this.values[number]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setCurve {
|
||||||
|
arg number, curve;
|
||||||
|
this.getInit(number).curve = curve;
|
||||||
|
}
|
||||||
|
|
||||||
|
setBounds {
|
||||||
|
arg number, min, max;
|
||||||
|
var controller = this.getInit(number);
|
||||||
|
controller.min = min;
|
||||||
|
controller.max = max;
|
||||||
|
}
|
||||||
|
|
||||||
|
at {
|
||||||
|
arg number;
|
||||||
|
var control = this.getInit(number);
|
||||||
|
var choices = (
|
||||||
|
value: this.getInit(number).currentValue.getSynchronous,
|
||||||
|
bus: this.getInit(number).currentValue,
|
||||||
|
map: this.getInit(number).currentValue.asMap,
|
||||||
|
kr: In.kr(this.getInit(number).currentValue),
|
||||||
|
);
|
||||||
|
^choices
|
||||||
|
}
|
||||||
|
|
||||||
|
connect {
|
||||||
|
MIDIClient.init;
|
||||||
|
MIDIIn.connectAll(verbose: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
installCallbacks {
|
||||||
|
MIDIIn.addFuncTo(\control, {
|
||||||
|
arg src, chan, num, val;
|
||||||
|
("CONTROL:" + (num + (this.currentBank * 24)) + "=>" + val).postln;
|
||||||
|
this.getInit(num + (this.currentBank * 24)).set(val);
|
||||||
|
});
|
||||||
|
MIDIIn.addFuncTo(\noteOn, {
|
||||||
|
arg src, chan, num, val;
|
||||||
|
"Changing bank".postln;
|
||||||
|
if (chan == 8 && num == 22) {
|
||||||
|
if (this.currentBank > 0) {
|
||||||
|
this.currentBank = this.currentBank - 1;
|
||||||
|
};
|
||||||
|
this.currentBank.postln;
|
||||||
|
};
|
||||||
|
if (chan == 8 && num == 24) {
|
||||||
|
if (this.currentBank < 3) {
|
||||||
|
this.currentBank = this.currentBank + 1;
|
||||||
|
};
|
||||||
|
this.currentBank.postln;
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
50
Classes/EventShortener.sc
Normal file
50
Classes/EventShortener.sc
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
EventShortener {
|
||||||
|
|
||||||
|
*findShortcuts {
|
||||||
|
arg pattern;
|
||||||
|
var short, correctedPattern;
|
||||||
|
correctedPattern = List.new();
|
||||||
|
short = Dictionary.newFrom([
|
||||||
|
// Instrument
|
||||||
|
\i, \instrument,
|
||||||
|
// Notes
|
||||||
|
\n, \note,
|
||||||
|
\mn, \midinote,
|
||||||
|
\vel, \velocity,
|
||||||
|
\deg, \degree,
|
||||||
|
\off, \timingOffset,
|
||||||
|
\o, \octave,
|
||||||
|
\f, \freq,
|
||||||
|
\det, \detune,
|
||||||
|
// Durations
|
||||||
|
\d, \dur,
|
||||||
|
\l, \legato,
|
||||||
|
// Amplitude
|
||||||
|
\p, \pan,
|
||||||
|
// Envelope
|
||||||
|
\a, \attack,
|
||||||
|
\d, \decay,
|
||||||
|
\s, \sustain,
|
||||||
|
\r, \release,
|
||||||
|
// Filter control
|
||||||
|
\r, \resonance,
|
||||||
|
\ff, \ffreq,
|
||||||
|
// Modulation
|
||||||
|
\m, \mod,
|
||||||
|
\mo, \midout,
|
||||||
|
\c, \midichan,
|
||||||
|
\st, \stretch,
|
||||||
|
\rt, \root,
|
||||||
|
\scl, \scale,
|
||||||
|
]);
|
||||||
|
|
||||||
|
// shortcuts are turned into regular keys;
|
||||||
|
pattern.do({| element |
|
||||||
|
if (short.includesKey(element),
|
||||||
|
{correctedPattern.add(short[element])},
|
||||||
|
{correctedPattern.add(element)}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
^correctedPattern;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,7 +0,0 @@
|
|||||||
FScope {
|
|
||||||
|
|
||||||
*new {
|
|
||||||
^Server.default.freqscope.window.alwaysOnTop_(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,3 +1,43 @@
|
|||||||
|
Scope {
|
||||||
|
|
||||||
|
*new {
|
||||||
|
^Server.default.scope.window.alwaysOnTop_(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Meter {
|
||||||
|
|
||||||
|
*new {
|
||||||
|
var window = Window.new(
|
||||||
|
"Meter",
|
||||||
|
Rect.new(left: 0, top: 0, width: 680, height: 250),
|
||||||
|
resizable: false,
|
||||||
|
border: true,
|
||||||
|
scroll: false
|
||||||
|
);
|
||||||
|
var meters = ServerMeterView.new(
|
||||||
|
Server.default, window,
|
||||||
|
0@0, 16, 16
|
||||||
|
);
|
||||||
|
window.front;
|
||||||
|
window.alwaysOnTop = true;
|
||||||
|
^window
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FScope {
|
||||||
|
|
||||||
|
*new {
|
||||||
|
^Server.default.freqscope.window.alwaysOnTop_(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Gui {
|
Gui {
|
||||||
|
|
||||||
*new {
|
*new {
|
||||||
|
|||||||
@ -1,28 +0,0 @@
|
|||||||
Scope {
|
|
||||||
|
|
||||||
*new {
|
|
||||||
^Server.default.scope.window.alwaysOnTop_(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Meter {
|
|
||||||
|
|
||||||
*new {
|
|
||||||
var window = Window.new(
|
|
||||||
"Meter",
|
|
||||||
Rect.new(left: 0, top: 0, width: 680, height: 250),
|
|
||||||
resizable: false,
|
|
||||||
border: true,
|
|
||||||
scroll: false
|
|
||||||
);
|
|
||||||
var meters = ServerMeterView.new(
|
|
||||||
Server.default, window,
|
|
||||||
0@0, 16, 16
|
|
||||||
);
|
|
||||||
window.front;
|
|
||||||
window.alwaysOnTop = true;
|
|
||||||
^window
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
30
Classes/Patterns/PXo.sc
Normal file
30
Classes/Patterns/PXo.sc
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
Pxo {
|
||||||
|
*new {
|
||||||
|
arg expression, divisor=1, repeats=inf;
|
||||||
|
var xoExp = Array.new(maxSize: expression.size);
|
||||||
|
expression.do({
|
||||||
|
arg char, i;
|
||||||
|
if (char == $x, {xoExp.add(1, i)}, {xoExp.add(Rest(), i)})
|
||||||
|
});
|
||||||
|
xoExp = xoExp.collect({arg item; item / divisor});
|
||||||
|
^Pseq.new(xoExp, repeats)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Ptx {
|
||||||
|
*new {
|
||||||
|
arg expression, repeats=inf;
|
||||||
|
var xoExp = Array.new(maxSize: expression.size);
|
||||||
|
expression.do({
|
||||||
|
arg char, i;
|
||||||
|
switch(char)
|
||||||
|
{$@} {xoExp.add(2, i)}
|
||||||
|
{$O} {xoExp.add(1, i)}
|
||||||
|
{$o} {xoExp.add(0.5, i)}
|
||||||
|
{$°} {xoExp.add(0.25, i)}
|
||||||
|
{} {xoExp.add(Rest(), i)};
|
||||||
|
});
|
||||||
|
^Pseq.new(xoExp, repeats)
|
||||||
|
}
|
||||||
|
}
|
||||||
12
Classes/Patterns/PwrapSeq.sc
Normal file
12
Classes/Patterns/PwrapSeq.sc
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
/* This one is taken from Mads Kjeldgaard's */
|
||||||
|
/* https://github.com/madskjeldgaard/Monolithic/blob/main/Classes/Pattern/PwrapSeq.sc */
|
||||||
|
PwrapSeq{
|
||||||
|
*new{
|
||||||
|
arg array, maxIndex, startIndex=0, repeats=inf;
|
||||||
|
|
||||||
|
var indexPat = Pseries.new(startIndex, 1, length: inf) % (maxIndex+1);
|
||||||
|
|
||||||
|
^Pindex.new(listPat: array, indexPat: indexPat, repeats: repeats)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user