Last active
February 25, 2021 21:15
-
-
Save scztt/f889e72d11ddcfb0879dbff82d531747 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
( | |
Pdef(\fmBase, Pbind( | |
\instrument, \fm, | |
// seed value | |
// Each integer increment of the seed is a different random configuration for the | |
// FM matrix. Non-integral values are cross-faded between adjacent integers (so 45.5 is | |
// 50% of 45 and 50% of 46). | |
// /seedDrift and /seedCurve affect how much the seed changes over the duration of the note. | |
\seed, 53, | |
\seedDrift, 0.3, | |
\seedDriftCurve, 4, | |
// freq offset of each operator, in hz | |
\freqMin, -10, | |
\freqMax, 10, | |
\freqRound, 0, | |
// freq multiplier for each op, where 0 is the fundamental, -1 is 1/2 fundamental. | |
// 1 is 2x fundamental, 2 is 3x fundamental etc. | |
\partialMin, 0, | |
\partialMax, 2, | |
// amount of the amp value for each slot in tbe matrix | |
\matrixMin, 0, | |
\matrixMax, 1, | |
\matrixCurve, 1, | |
// an extra amount to bump amp values for operator "feedback", e.g. | |
// the amount the operator gets from itself | |
\feed, 1, | |
// env | |
\attack, 0.01, | |
\sustainLevel, 0.5, | |
// randomly zero some matrix amp's, where 1 means none | |
// and 0 means all of them | |
\matrixCut, 0.8, | |
\dur, 1/2, | |
\legato, 2, | |
)).play; | |
) | |
( | |
// more interesting | |
Pdef(\fm, Pbind( | |
\dur, Pbjorklund2(5, 8) / 8, | |
\scale, Scale.chromatic, | |
\octave, Pseq([ | |
3, | |
[3, 4] | |
], inf).stutter(4), | |
\strum, 1/8, | |
\degree, Pstep(Pseq([0, -2], inf), 4, inf), | |
\degree, Pkey(\degree) + Pstep( | |
Pseq([0, 5], inf), | |
Pseq([3.6, 0.4], inf) | |
), | |
\seed, 53 + Pseg([0, 0.1], [4]).repeat, | |
\seedDrift, Pseg([-0.1, 0.9], [4]).repeat, | |
\seedDriftCurve, Pseg([-4, 4, -4], [16, 16]).repeat, | |
[\freqMin, \freqMax], Prand([ | |
[-0.2, 0.2], | |
[-2, 2], | |
[-8, 8] | |
], inf), | |
\partialMin, Pstep( | |
Pseq([0, -1], inf), | |
Pseq([5.5, 0.5], inf), | |
), | |
\partialMax, 2 | |
) <> Pdef(\fmBase) | |
).play | |
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
+UGen { | |
fadeChange { | |
|func, fadeTime=1, fadeClass=(XFade2)| | |
^[this].fadeChange(func, fadeTime=1, fadeClass=(XFade2)) | |
} | |
fadeTrig { | |
|func, fadeTime=1, fadeClass=(XFade2)| | |
^[this].fadeTrig(func, fadeTime=1, fadeClass=(XFade2)) | |
} | |
fadeSteps { | |
|func, stepSize=1, fadeClass=(LinXFade2), warp=0| | |
^[this].fadeSteps(func, stepSize, fadeClass, warp) | |
} | |
} | |
+ArrayedCollection { | |
fadeChange { | |
|func, fadeTime=1, fadeClass=(XFade2)| | |
var changed = this.collect { | |
|s| | |
if (s.rate == \control) { | |
s = K2A.ar(s); | |
}; | |
Impulse.ar(0) + Changed.ar(s); | |
}; | |
^(this * changed).fadeTrig(func, fadeTime, fadeClass); | |
} | |
fadeTrig { | |
|func, fadeTime=1, fadeClass=(XFade2)| | |
var trig, a, b, sig; | |
var meth = this.detect({ |s| s.rate == \audio }).notNil.if(\ar, \kr); | |
trig = Trig.perform(meth, this.sum, fadeTime); | |
trig = ToggleFF.perform(meth, trig); | |
a = Latch.perform(meth, this, 1 - trig); | |
b = Latch.perform(meth, this, trig); | |
a = func.value(*a); | |
b = func.value(*b); | |
^fadeClass.perform(a.rate.switch(\audio, \ar, \kr), | |
a, | |
b, | |
Delay1.perform(meth, Slew.perform(meth, trig, 1 / fadeTime, 1 / fadeTime)).linlin(0, 1, -1, 1) | |
); | |
} | |
fadeSteps { | |
|func, stepSize=1, fadeClass=(LinXFade2), warp=0| | |
var changed, a, b, sig, input, inputA, inputB, fade, isEvenStep; | |
input = (this / stepSize); | |
inputB = input.ceil; | |
inputA = input.floor; | |
isEvenStep = inputA % 2; | |
#inputA, inputB = Select.kr(isEvenStep, [ | |
[inputB, inputA], | |
[inputA, inputB] | |
]); | |
fade = (input - inputA).abs; | |
fade = ControlSpec(0, 1, warp).map(fade); | |
a = func.(stepSize * inputA); | |
b = func.(stepSize * inputB); | |
^fadeClass.perform(a.rate.switch(\audio, \ar, \kr), | |
a, | |
b, | |
(fade * 2 - 1) | |
); | |
} | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
( | |
SynthDef(\fm, { | |
var sig, env, gate, freqs, freqEnv, freqCurve, octs, phases, amps, matrix, freq; | |
var seed, seedA, seedB, seedBlend, sigA, sigB, params; | |
var freqMin, freqMax, partialMin, partialMax, freqRound, matrixMin, matrixMax, matrixCurve; | |
var attack, feed, sustain, inputFreq, pan; | |
var rand; | |
sustain = \sustain.kr(1); | |
seed = \seed.kr(0); | |
seed = seed + (\seedDrift.kr(0.05) * Env([0, 1], [sustain], [\seedDriftCurve.kr(0)]).kr(gate:1)); | |
// seed = seed + MouseX.kr(-3, 3); | |
rand = { | |
|seed, name, count| | |
count.collect { | |
|i| | |
Hasher.kr( | |
seed + i + ("name".hash % 1000.nthPrime) | |
) | |
} | |
}; | |
freqMin = \freqMin.kr(-1); | |
freqMax = \freqMax.kr(1); | |
freqRound = \freqRound.kr(0); | |
partialMin = \partialMin.kr(-1); | |
partialMax = \partialMax.kr(1); | |
inputFreq = \freq.kr; | |
freq = inputFreq; // * (ExpRand(0.01, 48) * Env([1, 0], [Rand(0.03, 0.2)], [-10]).kr(gate:1)).midiratio; | |
matrixMin = \matrixMin.kr(-1); | |
matrixMax = \matrixMax.kr(1); | |
matrixCurve = \matrixCurve.kr(0); | |
feed = \feed.kr(0); | |
gate = \gate.kr(1); | |
attack = \attack.kr(0.001).linlin(0, 1, 0.001, 1 - 0.001); | |
env = Env.adsr(attack, 1 - attack, \sustainLevel.kr(0.4), 0.3, curve:-9).kr(gate:gate, timeScale:sustain, doneAction:2); | |
freqs = seed.fadeSteps({ | |
|seed| | |
rand.(seed, "freqs", 6) | |
}, warp:\sin); | |
freqCurve = \freqCurve.kr(20); | |
freqEnv = Env.adsr( | |
attack, 1 - attack, 0, 0.3, curve:freqCurve * [1, -1, -1] | |
).kr(gate:gate, timeScale:sustain, doneAction:2); | |
freqs = freqs.linlin(-1, 1, freqMin, freqMax).round(freqRound); | |
amps = seed.fadeSteps({ | |
|seed| | |
[ | |
rand.(seed, "ampsScale", 6), | |
rand.(seed, "ampsEnv", 6), | |
rand.(seed, "ampsSustain", 6) | |
] | |
}, warp:\sin); | |
amps = [ | |
amps[0].linexp(-1, 1, 0.001, 1), | |
amps[1], | |
amps[2].lincurve(-1, 1, 0, 1, \ampSustainCurve.kr(-4)), | |
]; | |
amps[1] = ((amps[1] > 0) * (attack.pow(1 + (amps[1].linlin(0, 1, 0, 2))))) | |
+ ((amps[1] < 0) * (attack.pow(1 / (1 + (amps[1].linlin(0, 1, 0, 2)))))); | |
amps = amps.flop.collect { | |
|amp| | |
amp[0] * Env.adsr( | |
amp[1], 1 - amp[1], amp[2], 0.3 | |
).kr(gate:gate, timeScale:sustain); | |
}; | |
matrix = seed.fadeSteps({ | |
|seed| | |
rand.(seed, "matrix", 6*6) | |
* (rand.(seed, "matrixCut", 6*6) < \matrixCut.kr(1)) | |
}, warp:\sin); | |
matrix = matrix.lincurve(-1, 1, matrixMin, matrixMax, matrixCurve); | |
feed = feed * (1 + (env * 0.2)); | |
(7 * [0, 1, 2, 3, 4, 5]).do { | |
|i| | |
matrix[i] = matrix[i] + feed; | |
}; | |
sig = seed.fadeSteps({ | |
|seed| | |
var partial; | |
partial = rand.(seed, "partial", 6); | |
partial = partial.linlin(-1, 1, partialMin, partialMax).round(1); | |
partial = (1 + ((partial > 0) * partial)) | |
+ ((partial < 0) * (1 / (1 + partial.abs))); | |
// octs = [0, 0, 0, (0.188.ratiomidi), 0, 0]; | |
phases = rand.(seed, "phases", 6); | |
phases = phases.linexp(-1, 1, 0.001, 3); | |
FM7.ar( | |
[ | |
(freq * partial) + freqs, | |
phases, | |
amps | |
].flop, | |
matrix.clump(6) | |
).sum; | |
}, warp:\sin); | |
sig = env * sig; | |
pan = \pan.kr(0); | |
sig = Pan2.ar(sig, pan); | |
// sig = 24.dbamp * PanBin.ar(sig, 1.0, pan); | |
sig = Balance2.ar(sig[0], sig[1], pan * 0.3); | |
sig = \amp.kr(1) * sig; | |
OffsetOut.ar(\out.kr(0), sig.poll); | |
}).add; | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment