You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
175 lines
4.4 KiB
Plaintext
175 lines
4.4 KiB
Plaintext
// ===================================================
|
|
// SuperCollider: GrainFM Examples and Use Cases
|
|
// ===================================================
|
|
|
|
// Load this file into SuperCollider and evaluate each section as needed
|
|
|
|
// ---------------------------------------------------
|
|
// 1. Tonal Ambient Pad (Stable Pitch, Gentle Movement)
|
|
// ---------------------------------------------------
|
|
(
|
|
SynthDef(\grainFMPadClean, {
|
|
|out=0, freq=440, amp=0.3, dur=10|
|
|
var trig = Impulse.kr(15); // grains per second
|
|
var snd;
|
|
|
|
snd = GrainFM.ar(
|
|
numChannels: 2,
|
|
trigger: trig,
|
|
dur: 0.2,
|
|
carfreq: freq,
|
|
modfreq: freq * 2, // simple ratio
|
|
index: 1.5,
|
|
pan: LFNoise1.kr(0.2),
|
|
envbufnum: -1
|
|
);
|
|
|
|
snd = snd * EnvGen.kr(Env.linen(1, dur-2, 1), doneAction: 2) * amp;
|
|
Out.ar(out, snd);
|
|
}).add;
|
|
)
|
|
|
|
// Example usage:
|
|
Synth(\grainFMPadClean, [\freq, 330, \dur, 12]);
|
|
|
|
// ---------------------------------------------------
|
|
// 2. Cloudy Texture (Randomized Frequencies)
|
|
// ---------------------------------------------------
|
|
(
|
|
SynthDef(\grainFMCloud, {
|
|
|out=0, amp=0.2, dur=8|
|
|
var trig = Dust.kr(25);
|
|
var freq = TExpRand.kr(200, 800, trig);
|
|
var snd;
|
|
|
|
snd = GrainFM.ar(
|
|
numChannels: 2,
|
|
trigger: trig,
|
|
dur: 0.1,
|
|
carfreq: freq,
|
|
modfreq: freq * 1.5,
|
|
index: TRand.kr(1, 10, trig),
|
|
pan: TRand.kr(-1, 1, trig),
|
|
envbufnum: -1
|
|
);
|
|
|
|
snd = snd * EnvGen.kr(Env.linen(1, dur-2, 1), doneAction: 2) * amp;
|
|
Out.ar(out, snd);
|
|
}).add;
|
|
)
|
|
|
|
Synth(\grainFMCloud);
|
|
|
|
// ---------------------------------------------------
|
|
// 3. Evolving Drone (Slow Modulation of Grain Rate & Pitch)
|
|
// ---------------------------------------------------
|
|
(
|
|
SynthDef(\grainFMEvolvingDrone, {
|
|
|out=0, baseFreq=100, amp=0.3, dur=20|
|
|
var trig = Impulse.kr(LFNoise1.kr(0.1).range(5, 30));
|
|
var freq = LFNoise1.kr(0.05).range(baseFreq, baseFreq * 4);
|
|
var modfreq = freq * LFNoise1.kr(0.02).range(0.5, 2);
|
|
var snd;
|
|
|
|
snd = GrainFM.ar(
|
|
numChannels: 2,
|
|
trigger: trig,
|
|
dur: 0.15,
|
|
carfreq: freq,
|
|
modfreq: modfreq,
|
|
index: 3,
|
|
pan: LFNoise1.kr(0.3),
|
|
envbufnum: -1
|
|
);
|
|
|
|
snd = snd * EnvGen.kr(Env.linen(2, dur-4, 2), doneAction: 2) * amp;
|
|
Out.ar(out, snd);
|
|
}).add;
|
|
)
|
|
|
|
Synth(\grainFMEvolvingDrone);
|
|
|
|
// ---------------------------------------------------
|
|
// 4. Percussive Metallic Hits
|
|
// ---------------------------------------------------
|
|
(
|
|
SynthDef(\grainFMHit, {
|
|
|out=0, freq=400, amp=0.4|
|
|
var trig = Impulse.kr(1);
|
|
var snd;
|
|
|
|
snd = GrainFM.ar(
|
|
numChannels: 2,
|
|
trigger: trig,
|
|
dur: 0.05,
|
|
carfreq: freq,
|
|
modfreq: freq * 3,
|
|
index: 12,
|
|
pan: 0,
|
|
envbufnum: -1
|
|
);
|
|
|
|
snd = snd * EnvGen.kr(Env.perc(0.01, 0.3), doneAction: 2) * amp;
|
|
Out.ar(out, snd);
|
|
}).add;
|
|
)
|
|
|
|
Synth(\grainFMHit);
|
|
|
|
// ---------------------------------------------------
|
|
// 5. Blending with a Pure Tone (Stable Pitch)
|
|
// ---------------------------------------------------
|
|
(
|
|
SynthDef(\grainFMWithTone, {
|
|
|out=0, freq=440, amp=0.3, dur=10|
|
|
var trig = Impulse.kr(20);
|
|
var grain = GrainFM.ar(2, trig, 0.15, freq, freq * 2, 2, LFNoise1.kr(0.2), -1);
|
|
var tone = SinOsc.ar(freq) * 0.1;
|
|
var sig = Mix([grain, tone]);
|
|
|
|
sig = sig * EnvGen.kr(Env.linen(1, dur-2, 1), doneAction: 2) * amp;
|
|
Out.ar(out, sig);
|
|
}).add;
|
|
)
|
|
|
|
Synth(\grainFMWithTone);
|
|
|
|
// ---------------------------------------------------
|
|
// 6. MIDI-Controlled GrainFM Synth (For Sequencing)
|
|
// ---------------------------------------------------
|
|
(
|
|
SynthDef(\grainFMMidi, {
|
|
|out=0, freq=440, amp=0.3, gate=1|
|
|
var trig = Impulse.kr(10);
|
|
var snd;
|
|
|
|
snd = GrainFM.ar(
|
|
numChannels: 2,
|
|
trigger: trig,
|
|
dur: 0.2,
|
|
carfreq: freq,
|
|
modfreq: freq * 2,
|
|
index: 2,
|
|
pan: LFNoise1.kr(0.2),
|
|
envbufnum: -1
|
|
);
|
|
|
|
snd = snd * EnvGen.kr(Env.asr(0.01, 1, 1), gate, doneAction: 2) * amp;
|
|
Out.ar(out, snd);
|
|
}).add;
|
|
)
|
|
|
|
(
|
|
MIDIIn.connectAll;
|
|
|
|
~grainFMResponder = NoteOnResponder({
|
|
|src, chan, num, vel|
|
|
var freq = num.midicps;
|
|
Synth(\grainFMMidi, [\freq, freq, \amp, vel/127]);
|
|
});
|
|
)
|
|
|
|
// ---------------------------------------------------
|
|
// You can now play GrainFM like an instrument from a MIDI controller!
|
|
// ---------------------------------------------------
|