hey, i admire your work on this but have a hard time to follow the discussion.
im using the midisynth class from this thread Video Tutorials on MIDI based music production with Supercollider, jackd and DAW - #10 by droptableuser advanced by the oportunity to specify a specific tuning
MidiSynth : Ndef {
var <synthdef, <hasGate, <instrument;
var <noteonkey, <noteoffkey, <cckey;
*new {|key|
var res = Ndef.dictFor(Server.default).envir[key];
if (res.isNil) {
res = super.new(key).prInit;
};
^res;
}
prInit {
noteonkey = "%_noteon".format(this.key).asSymbol;
noteoffkey = "%_noteff".format(this.key).asSymbol;
cckey = "%_cc".format(this.key).asSymbol;
^this;
}
note {|noteChan, note, root(0), tuning|
MIDIdef.noteOn(noteonkey, {|vel, note, chan|
var tunedNote = note - root;
tunedNote = tuning.wrapAt(tunedNote)
+ tunedNote.trunc(tuning.stepsPerOctave)
+ root;
if (this.hasGate) {
this.put(note, instrument, extraArgs:[
\freq, tunedNote.midicps, \vel, vel/127, \gate, 1])
} {
this.put(note, instrument, extraArgs:[
\freq, tunedNote.midicps, \vel, vel/127])
}
}, noteNum:note, chan:noteChan)
.fix;
MIDIdef.noteOff(noteoffkey, {|vel, note, chan|
if (this.hasGate) {
this.objects[note].set(\gate, 0);
}
}, noteNum:note, chan:noteChan)
.fix;
}
synth {|synth|
synthdef = SynthDescLib.global.at(synth);
instrument = synth;
hasGate = synthdef.hasGate;
this.prime(synth);
}
cc {|ctrl, ccNum, ccChan=0|
var order = Order.newFromIndices(ctrl.asArray, ccNum.asArray);
MIDIdef.cc(cckey, {|val, num|
var ctrl = order[num];
var spec = if (this.getSpec(ctrl).notNil) {
this.getSpec(ctrl)
}{
[0, 1].asSpec;
};
var mapped = spec.map(val/127);
this.set(ctrl, mapped);
}, ccNum:ccNum, chan:ccChan)
.fix;
}
disconnect {
MIDIdef.noteOn(noteonkey).permanent_(false).free;
MIDIdef.noteOff(noteoffkey).permanent_(false).free;
MIDIdef.cc(cckey).permanent_(false).free;
}
}
(
(1..50).do({|partials|
SynthDef(\additive ++ partials, {
var sig, freqs, gainEnv;
gainEnv = EnvGen.ar(Env.adsr(
\atk.kr(0.07),
\dec.kr(0.5),
\sus.kr(1),
\rel.kr(2),
curve: \curve.kr(-4)
), \gate.kr(1), doneAction:2);
freqs = Array.fill(partials, {|i|
\freq.kr(20) * (i+1);
});
sig = freqs.collect({|freq, i|
var amps = \decay.kr(0.5) / (i+1);
SinOsc.ar(freq) * amps;
});
sig = Mix(sig);
sig = sig * gainEnv * \amp.kr(0.3) * \vel.kr(1);
sig = Splay.ar(sig);
Out.ar(\out.kr(0), sig)
}).add;
});
)
(
MidiSynth(\m1).synth(\additive10);
MidiSynth(\m1).note(noteChan:0, root: 7, tuning: Tuning.at(\just)).cc(ctrl:[
\atk,
\dec,
\sus,
\rel,
\curve,
\amp,
\vel,
\out,
], ccNum:(1..8), ccChan:0);
MidiSynth(\m1).addSpec(
\atk, [0.07, 8],
\dec, [0.5, 4],
\sus, [0.07, 8],
\rel, [0.07, 20],
\curve, [(-4), 4],
\amp, [0, 1],
\vel, [0, 1],
\out, [0, 1],
).edit;
)
and also encountered the issue of using an exisiting SynthDef for an fx chain.
how can this be done without rewriting the fx SynthDef as a function like this:
~granular_reverb = {
arg in=0, overlap=0.6, minGrainDur=0.001,
tFreq=2, tFreqMF=0, tFreqMD=0,
rate=1, rateMF=0, rateMD=0,
offset=0.015, offsetMF=0, offsetMD=0;
var sig, readPos, writePos, grainDur;
var trig, bufFrames, sndBuf, bufDur;
var tFreqMod = {
SinOsc.ar(tFreqMF, Rand(0.0,2pi)) * tFreqMD;
};
var rateMod = {
SinOsc.ar(rateMF, Rand(0.0,2pi)).range(0, rateMD);
};
var offsetMod = {
SinOsc.ar(offsetMF, Rand(0.0,2pi)).range(0, offsetMD);
};
tFreq = tFreq + tFreqMod.dup;
rate = rate - rateMod.dup;
bufFrames = 2**16;
sndBuf = {LocalBuf(bufFrames).clear}!2;
bufDur = BufDur.ir(sndBuf);
writePos = Phasor.ar(end: bufFrames);
trig = Impulse.ar(tFreq, [0, \rightTriggerPhase.kr(0.25)]);
grainDur = max(tFreq.reciprocal * overlap.lag(5), minGrainDur);
readPos = writePos - 64 / bufFrames - offset - offsetMod.dup;
readPos = Wrap.ar(readPos, 0, 1);
sig = GrainBufJ.ar(
numChannels: 1,
loop: 1,
trigger: trig,
dur: grainDur,
sndbuf: sndBuf,
rate: rate,
pos: readPos,
interp: 4,
pan: 0,
);
sig = HPF.ar(sig, \grHpf.kr(90));
sig = LPF.ar(sig, \grLpf.kr(12500));
// writing granulated sig + input back to grain buffer
sndBuf.do { |b i|
BufWr.ar(sig[i] * \feedback.kr(0.1) + in[i], b, writePos)
};
sig.tanh;
};
and then using:
(
MidiSynth(\m1).filter(210, ~granular_reverb).set(
\rate, 2.00,
\tFreq, 5.0,
\offset, 0.15,
\rateMD, 0.0,
\tFreqMD, 5.0,
\offsetMD, 0.0,
\rateMF, 0.25,
\tFreqMF, 2.0,
\offsetMF, 0.15,
\grHpf, 75.0,
\grLpf, 9500.0,
\overlap, 1,
\rightTriggerPhase, 0.25,
\feedback, 0.1,
\wet210, 1,
);
)
to make the fx chain? thanks a lot.