Skip to content

Instantly share code, notes, and snippets.

@scztt
Last active March 15, 2021 15:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save scztt/b122b93eba29bfae3b77056c0f04c7e4 to your computer and use it in GitHub Desktop.
Save scztt/b122b93eba29bfae3b77056c0f04c7e4 to your computer and use it in GitHub Desktop.
(
SynthDef(\test, {
var gate, tgate, env, sig;
gate = \gate.kr(1);
tgate = \tgate.tr(1);
env = Env.perc(0, \sustain.kr).kr(gate:tgate, doneAction:2);
sig = Saw.ar(\freq.kr.lag(0.2)) * env;
Out.ar(\out.kr(0), sig ! 2);
}).add;
Pdef(\roundRobin, Prout({
|event|
var voiceStreams = 4.collect {
PmonoReuse(event[\instrument]).asStream;
};
var index = 0;
loop {
event = event.putAll(voiceStreams[index].next(event));
index = (index + 1) % voiceStreams.size;
event = event.yield;
}
}));
Pdef(\foo, Pdef(\roundRobin) <> Pbind(
\instrument, \test,
\tgate, 1,
\sustain, Pwhite(0.25, 2.0),
\degree, Pwhite(0, 12),
\dur, Prand([0.25, 0.25, 1.0], 40)/2
)).play
)
(
Event.partialEvents[\nodeObjectEvent] = (
nodeObject: {
|self|
self.use {
var nodeObj = ~id.asArray.collect {
|id|
switch (~type,
\note, {
Synth.basicNew(~instrument, ~server, id).isRunning_(true)
},
\group, {
Group.basicNew(~server, id).isRunning_(true)
},
{
Node.basicNew(~server, id).isRunning_(true)
}
)
};
switch (
nodeObj.size,
0, { nil },
1, { ~nodeObject = nodeObj[0] },
{ ~nodeObject = nodeObj }
)
}
},
setupOnFree: {
|self|
~nodeObject.value(self) !? {
|nodeObj|
~setupOnFree = nil;
nodeObj.asArray.do ({
|n|
n.onFree({
self.use { ~onFreeAction.(n) }
})
})
};
},
onFree: {
|self, action|
self.use {
if (action.notNil) {
~setupOnFree.(self);
~onFreeAction = ~onFreeAction.addFunc(action);
};
}
},
voiceLimit: 4
);
Event.parentEvents.default.putAll(Event.partialEvents.nodeObjectEvent);
Event.parentEvents.synthEvent.putAll(Event.partialEvents.nodeObjectEvent);
Event.parentEvents.groupEvent.putAll(Event.partialEvents.nodeObjectEvent);
)
PmonoReuseStream : PmonoStream {
var scheduledNoteOffFunc;
embedInStream { |inevent|
var sustain, rearticulating = true;
inevent ?? { ^nil.yield };
this.prInit(inevent);
loop {
if(this.prDoStreams) {
if(rearticulating or: { event[\id].isNil } and: { event.isRest.not }) {
event[\id] = nil;
this.prInitNode;
rearticulating = false;
// Log(\PmonoReuse).info("rearticulating = %", rearticulating);
event.onFree({
// Log(\PmonoReuse).info("Event ended, so ditching cleanup funcs...");
inevent[\removeFromCleanup] = inevent[\removeFromCleanup].add(currentCleanupFunc);
currentCleanupFunc = nil;
rearticulating = true;
});
};
sustain = event.use { ~sustain.value };
thisThread.clock.sched(sustain, scheduledNoteOffFunc = {
if (thisFunction == scheduledNoteOffFunc) {
// Log(\PmonoReuse).info("schedule cleanup");
currentCleanupFunc.value(true);
currentCleanupFunc = nil;
rearticulating = true;
}
});
cleanup.update(event);
inevent = event.yield;
this.prSetNextEvent(inevent);
} {
^cleanup.exit(inevent)
}
}
}
}
PmonoReuse : Pmono {
embedInStream { |inevent|
^PmonoReuseStream(this).embedInStream(inevent)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment