EnvGen forced release can no longer be done during main release
[email protected] Mon, 2 Mar 2020 08:23:53 +0800
| Newsgroups | gmane.comp.audio.supercollider.devel |
|---|---|
| Message-ID | <CAFniQ7U2Npojr=gVdMToDbBhYiaJzuSkrg_QbkCGnQUOYeu3Aw@mail.gmail.com> |
Hm. I think I found something that drifted a few years ago.
Because of some discussions about EnvGen forced-release, I was
thinking about this use case:
- User defines an envelope with a long release segment.
- Uses Voicer to play the SynthDef.
- At some point, there are too many nodes (one of the functions of
Voicer is to control the number of active nodes), so Voicer sends a
forced-release to the oldest node before playing the new one.
I had been assuming that forced-release would always take precedence
-- so the old node would be stolen within 10-20 ms.
But I find out today that this isn't actually the case (anymore).
s.boot;
(
SynthDef(\test, { |out, gate = 1, freq = 440, amp = 0.1|
var eg = EnvGen.kr(Env.adsr(0.2, 0.5, 0.5, 2.5), gate, doneAction: 2),
sig = SinOsc.ar(freq);
Out.ar(out, (sig * amp * eg).dup);
}).add;
)
(
f = { |node, releaseTime|
var now = SystemClock.seconds,
resp = OSCFunc({
resp.free;
"Released after % seconds\n".postf(SystemClock.seconds - now);
}, '/n_end', s.addr, argTemplate: [node.nodeID]);
node.release(releaseTime);
};
)
a = Synth(\test);
(
fork {
f.(a); // normal release
0.3.wait;
f.(a, 0.01); // emergency release, I MEAN NOW
}
)
Released after 2.489311822 seconds // expected about 0.31 here
Released after 2.189311822 seconds // expected about 0.01 here
https://github.com/supercollider/supercollider/commit/4a0e9190982982fc38f94e8a35390038b39833f5
`else if (gate <= -1.f && prevGate > -1.f && !unit->m_released)`
`&& !unit->m_released` is new here. It was introduced for good reason
-- without it, there were cases where EnvGen inflooped (bug #753).
But it changed the meaning of a forced release: you can no longer
force a quick release of a synth that is already releasing.
In hindsight, a better solution might have been to introduce another
flag unit->m_force_released:
- `else if (gate <= -1.f && prevGate > -1.f && !unit->m_force_released)`
- and later, `else if (prevGate > 0.f && gate <= 0.f &&
unit->m_releaseNode >= 0 && !unit->m_released &&
!unit->m_force_released)`
Not logging an issue yet because we should probably figure out what
"forced release" is really supposed to mean -- but, the referenced bug
fix does break node control in Voicer. (It was understandable for that
bug to be fixed in that way: we have no functional specs, so nobody
knows what anything means, so devs are free to change behavior at
will. I'm suggesting in this case we should restore the original
meaning while still fixing the bug.)
hjh
_______________________________________________
sc-dev mailing list
info (subscription, etc.): http://www.birmingham.ac.uk/facilities/ea-studios/research/supercollider/mailinglist.aspx
archive: http://www.listarc.bham.ac.uk/marchives/sc-dev/
search: http://www.listarc.bham.ac.uk/lists/sc-dev/search/