fm pulsar wave terrain
parent
045bea520e
commit
c5763d99da
@ -0,0 +1,117 @@
|
||||
(
|
||||
// Generate a terrain table
|
||||
~terrain = Buffer.alloc(s, 1024, 1);
|
||||
~terrain.sine1([1, 0.5, 0.3, 0.2, 0.1], true); // You can sculpt this more chaotically
|
||||
|
||||
SynthDef("fm_pulsar_terrain", {
|
||||
arg a, e, f, d;
|
||||
var t, overlap, carfreq, modfreq, mInd, vel, vel_, tblPos, sig;
|
||||
|
||||
f = \freq.kr(100);
|
||||
|
||||
vel = \kel.kr(0.5);
|
||||
vel_ = vel.clip(0,1.0).linlin( 0, 1, 2, 0.7);
|
||||
|
||||
e = EnvGen.kr(
|
||||
Env.adsr(
|
||||
\att.kr(0.025) * vel_,
|
||||
\dec.kr(0.02) * vel_,
|
||||
\susl.kr(0.7),
|
||||
\rel.kr(4),
|
||||
curve: \curve.kr(-4)
|
||||
),
|
||||
gate: \gate.kr(1),
|
||||
doneAction:2
|
||||
) * vel;
|
||||
|
||||
carfreq = f * \cf.kr(2) + LFNoise1.kr(3).range(0,50);
|
||||
modfreq = carfreq * \mf.kr(2) + LFNoise1.kr(3).range(0,100);
|
||||
|
||||
t = Impulse.ar(f);
|
||||
|
||||
mInd = e.pow(3.3); // use envelope shape to shift table pos
|
||||
overlap = 1.1 - e.pow(0.5);
|
||||
d = overlap / f;
|
||||
|
||||
// convert modfreq to index between 0 and 1 for VOsc
|
||||
tblPos = modfreq.linlin(0, 8000, 0, 1).wrap(0, 1); // safer than clip for edge cases
|
||||
|
||||
a = Mix([
|
||||
SinOsc.ar(f),
|
||||
GrainBuf.ar(1, t, d, ~terrain, tblPos, carfreq, 0, 2)
|
||||
]);
|
||||
|
||||
a = LeakDC.ar(a * e);
|
||||
Out.ar(\outBus.kr(0), a.dup * \gain.kr(0.1));
|
||||
|
||||
}).add;
|
||||
)
|
||||
|
||||
Synth(\fm_pulsar_terrain);
|
||||
|
||||
|
||||
|
||||
(
|
||||
// MIDI
|
||||
// EMF: one major issue here is that ~notes is never actually initialized as an array, so it's nil. when you try to store a Synth at index nn, SC throws an error, because you can't put an item into nil. So, we first initialize ~notes as an array of size 128. After I add this line, your polyphonic MIDI code seems to work fine (no stuck notes)
|
||||
|
||||
~notes = Array.newClear(128);
|
||||
|
||||
MIDIdef.noteOn(\noteOnTest, {
|
||||
arg vel, nn, chan, src;
|
||||
[vel, nn].postln;
|
||||
|
||||
if (chan == 0, {
|
||||
~notes[nn] = Synth.new(
|
||||
\fm_pulsar_terrain,
|
||||
[
|
||||
\freq, nn.midicps,
|
||||
\amp, vel.linexp(1,127,0.01,0.3),
|
||||
// \gate, 1,
|
||||
|
||||
]
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
MIDIdef.noteOff(\noteOffTest, {
|
||||
arg vel, nn, chan;
|
||||
[vel, nn].postln;
|
||||
|
||||
if (chan == 0, {
|
||||
~notes[nn].set(\gate, 0);
|
||||
~notes[nn] = nil;
|
||||
});
|
||||
});
|
||||
|
||||
[
|
||||
[\freq, 0, 50, 4000],
|
||||
[\amp, 1, 0.0, 1.5],
|
||||
[\cf, 2, 0.1, 4.0],
|
||||
[\mf, 3, 0.1, 4.0],
|
||||
[\tblIndex, 4, 0.0, 1.0],
|
||||
[\gain, 5, 0.01, 1.0],
|
||||
[\att, 6, 0.001, 0.2],
|
||||
[\dec, 7, 0.001, 0.2],
|
||||
[\rel, 8, 0.1, 8.0],
|
||||
[\susl, 9, 0.0, 1.0],
|
||||
[\curve, 10, -8.0, 8.0],
|
||||
[\kel, 11, 0.0, 1.0]
|
||||
].do { |spec|
|
||||
var param, cc, min, max;
|
||||
#param, cc, min, max = spec;
|
||||
|
||||
MIDIdef.cc(param.asSymbol, { |val, num, chan, src|
|
||||
if (chan == 2) {
|
||||
var mapped = val.linlin(0, 127, min, max);
|
||||
~pulsar.set(param, mapped);
|
||||
}
|
||||
}, cc);
|
||||
};
|
||||
)
|
||||
|
||||
|
||||
(
|
||||
MIDIClient.init;
|
||||
MIDIIn.connectAll;
|
||||
)
|
||||
Loading…
Reference in New Issue