-
-
Save lgvr123/ad5f501f7b8d6f9dacde6e1bc2777518 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
~prolongeCore = { | |
// arguments du constructeur | |
// arg numChannels, params; | |
arg numChannels, params, | |
nbuf=0, bBufnum, cBufnum, blend=0.1; | |
var natural=params.atFail(\natural_release,0); // par défaut, le mode est "Gated Release"; | |
// argument du synth | |
// var nbuf=\nbuf.ir(0), bBufnum = \bBufnum.ir, cBufnum=\cBufnum.ir; // v7 : to regular argument | |
var atk=\atk.ir(0.1),rel=\rel.kr(0.1); | |
// var blend=\blend.kr(0.1); // v7 : to regular argument | |
var bufStart=\bufStart.ir(-1), cueStart=\cueStart.ir(-1); | |
var gate=\gate.kr(1); | |
var bufidx1=0,bufnum1,ncue1=1,cueidx10=0, cueidx11=1, offset1, start1, end1; | |
var idx1, gate1, sig1, rel1; | |
var bufidx2=0,bufnum2,ncue2=1,cueidx20=0, cueidx21=1, offset2, start2, end2; | |
var idx2, gate2, sig2, rel2; | |
var trig1,trig2; | |
var sig, env; | |
var bfs, cus; | |
var trig0=Impulse.kr(0); | |
var isstart; | |
// debug | |
var poll=Impulse.kr(10); | |
var elapsed=Sweep.kr(trig0,1); | |
// loop 1 | |
// .. buffer and cue points choice | |
rel2=LocalIn.kr(1,0); | |
trig1=rel2+Impulse.kr(0); // loop1's trigger is an initial trigger + the release of the loop2 | |
isstart=SetResetFF.kr(rel2); // On est dans 1ère itération tant que on n'a pas le 1er "rel2" | |
// .. buffer and cue points choice | |
// Poll.kr(poll,elapsed,"*****"); | |
// - Buffer to be used at start | |
if (bufStart.isNil) {bfs=-1} {bfs=bufStart}; | |
bfs=bfs.clip(-1,nbuf-1); | |
bfs=Select.kr(isstart,[bfs,(-1)]); // à la 1ère itération, si bufStart<>-1, alors on ommence avec ce buffer, sinon on choisit au hazard. | |
bufidx1=Select.kr(bfs+1,[TIRand.kr(0,nbuf-1,trig1),bfs]);// randomly select the buffer index for the loop1 | |
bufnum1=Index.kr(bBufnum,bufidx1); // bufnum the choosen buffer | |
// - Buffer to be used at start | |
ncue1=Index.kr(bBufnum,nbuf+bufidx1); // # cue points for that buffer | |
if (cueStart.isNil) {cus=-1} {cus=cueStart}; | |
cus=cus.clip(-1,ncue1-2); | |
cus=Select.kr(isstart,[cus,(-1)]); // à la 1ère itération, si cueStart<>-1, alors on ommence à cette position, sinon on choisit au hazard. | |
cueidx10=Select.kr(cus+1,[TIRand.kr(0,ncue1-2,trig1), cus]);// randomly select a start cuepoint | |
cueidx11=TIRand.kr(cueidx10+1,ncue1-1,trig1); // randomly select a end cuepoint (after the start cuepoint) | |
offset1=Index.kr(bBufnum,2*nbuf+bufidx1); // offset for the buffer in the cuepoint array/buffer | |
start1=Index.kr(cBufnum,offset1+cueidx10); // real start cuepoint | |
end1=Index.kr(cBufnum,offset1+cueidx11); // real end cue point | |
Poll.kr(trig1,bufidx1,"* buf 1"); | |
Poll.kr(trig1,start1,"- cue 1 start"); | |
Poll.kr(trig1,end1,"- cue 1 end"); | |
// En mode "Natural release", on s'arrête à la fin du sample quand le Gate est déclenché | |
if(natural==1) { | |
end1=(gate*end1)+((1-gate)*BufFrames.kr(bufnum1)); | |
}; | |
// ..sweep and read | |
idx1=Sweep.ar(trig1, BufSampleRate.kr(bufnum1))+start1; | |
sig1=BufRd.ar(numChannels, bufnum1, idx1, 0);// 1: mono, 2: stereo | |
// .. gate | |
rel1=Trig1.kr(idx1-end1,0); // release when end cue point is reached | |
gate1=SetResetFF.kr(trig1,rel1); // build a gate to be used in SelectX | |
// loop 2 | |
trig2=rel1; // loop2's trigger is loop1's release | |
// .. buffer and cue points choice | |
bufidx2=TIRand.kr(0,nbuf-1,trig2); | |
bufnum2=Index.kr(bBufnum,bufidx2); | |
ncue2=Index.kr(bBufnum,nbuf+bufidx2); | |
cueidx20=TIRand.kr(0,ncue2-2,trig2); | |
cueidx21=TIRand.kr(cueidx20+1,ncue2-1,trig2); | |
offset2=Index.kr(bBufnum,2*nbuf+bufidx2); | |
start2=Index.kr(cBufnum,offset2+cueidx20); | |
end2=Index.kr(cBufnum,offset2+cueidx21); | |
Poll.kr(trig2,bufidx2,"* buf 2"); | |
Poll.kr(trig2,start2,"- cue 2 start"); | |
Poll.kr(trig2,end2,"- cue 2 end"); | |
// En mode "Natural release", on s'arrête à la fin du sample quand le Gate est déclenché | |
if(natural==1) { | |
end2=(gate*end2)+((1-gate)*BufFrames.kr(bufnum2)); | |
}; | |
// ..sweep and read | |
idx2=Sweep.ar(trig2, BufSampleRate.kr(bufnum2)) + start2; | |
sig2=BufRd.ar(numChannels, bufnum2, idx2, 0);// 1: mono, 2: stereo | |
// .. gate | |
rel2=Trig1.kr(((1-gate1)*idx2)-end2,0); // release when end cue point is reached // ==> "(1-gate1)*idx2" : Limit analyse to the portion where loop2 is expected to play. Without this we face nonexpected starts | |
gate2=SetResetFF.kr(trig2,rel2); | |
// Poll.kr(trig1,end1, "--TRIG 1-- delay1"); | |
// Poll.kr(rel1,end1, "--REL1 1-- delay1"); | |
// Poll.kr(trig2,end2, "--TRIG 2-- delay2"); | |
// Poll.kr(rel2,end2, "--REL 2-- delay2"); | |
LocalOut.kr([rel2]); | |
// En mode "Natural release", on s'arrête à la fin du sample | |
if(natural==1) { | |
// Astuce: pour savoir si je dois utiliser rel1 pour finir le Synth, | |
// la logique voudrait qu'on écrive gate1*rel1 (et respectivemnt | |
// pour rel2 (1-gate1)*rel1. | |
// MAIS rel1 fait baculer gate1 à 0. Idem pour rel2 qui fait | |
// basculer gate1 à 1. | |
// DONC: il faut écrire (1-gate1)*rel1, aka gate2*rel1 et non gate1*rel1 | |
FreeSelf.kr((1-gate)*( ((1-gate1)*rel1) + ((gate1)*rel2))); | |
}; | |
sig=SelectX.ar(Lag.kr(1-gate1,blend),[sig1,sig2]); | |
// En mode "Gated release", on rajoute une envelope | |
if(natural==0) { | |
env=EnvGen.kr(Env.asr(atk,1,rel),gate,doneAction: 2); | |
sig=sig*env; | |
}; | |
// return | |
sig; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment