musikinformatik / SuperDirt

Tidal Audio Engine
GNU General Public License v2.0
525 stars 76 forks source link

Safety limit with override #166

Open yaxu opened 4 years ago

yaxu commented 4 years ago

Add for gain and shape, ref https://github.com/tidalcycles/Tidal/issues/588

yaxu commented 4 years ago

I noticed that shape now just goes silent for values >= 1. So perhaps this should be limited to 0.99999 anyway.

yaxu commented 4 years ago

It was already limited to < 1, so no need for overshape at all - it's removed now.

yaxu commented 4 years ago

killtime on the chat reports blowing macbook speakers by setting bpf to 576000000

What's a good limit for lpf, bpf and hpf? (and maybe lpf / bpq / hpq)

bgold-cosmos commented 4 years ago

I believe all the resonances are hard-limited in SuperDirt, and usually the lower limit of the frequencies (LPFs tend to blow up at zero frequency). I can check and put together a PR. An upper limit of 80 kHz ought to be plenty safe?

telephon commented 4 years ago

The limit depends on your sample rate.

yaxu commented 4 years ago

Fixed, thanks @bgold-cosmos https://github.com/musikinformatik/SuperDirt/pull/173

yaxu commented 4 years ago

Here's an example of @lwlsn performance with an lpf of 30k blowing up (should jump to 6m32s) - should we set the limit lower or is this an issue with the filter? https://youtu.be/CrSVuM3nXeA?t=392

yaxu commented 4 years ago

Later in the performance superdirt struggles a bit with high polyphony vs the stream capture.. Is there a setting to limit polyphony? (Either by stopping oldest sounds or not playing the newest one)

telephon commented 4 years ago

Here's an example of @lwlsn performance with an lpf of 30k blowing up

sure, this will blow up. Limits are easy to add if necessary.

Is there a setting to limit polyphony?

no, but we could add one.

Either by stopping oldest sounds or not playing the newest one

the former is a little more complicated than the latter, the latter may be confusing, however.

telephon commented 4 years ago

Here is a branch with voice stealing, can you test?

https://github.com/musikinformatik/SuperDirt/tree/steal-voices

You can set the limit by:

~dirt.set(\maxVoices, 20); // <---- default is inf
bgold-cosmos commented 4 years ago

What I'm a bit surprised about is that there's already a limit of SampleRate.ir/2 in the LPF, but maybe it's not real well-behaved right at the limit?

telephon commented 4 years ago

It may behave erratically, because many synths at once may receive the signal and release slowly, so I'm not sure. But this is the easy first step.

telephon commented 4 years ago

I've added a lg parameter, which you can adjust with

~dirt.set(\maxVoices, 20); // <---- default is inf
~dirt.set(\maxVoicesLag, 0.2);

The larger it is the more leeway it gives to go beyond limit, but releases fewer nodes.

Needs to be tested.

telephon commented 4 years ago

Needs to be tested.

I just tested it, the approach doesn't work too well, sorry.

telephon commented 4 years ago

Here's an example of @lwlsn performance with an lpf of 30k blowing up (should jump to 6m32s)

I tried to reconstruct this, but didn't manage to. The filters are already protected, I saw. Maybe that was a different version?

d1 $ sound "hh:2" # lpf 30000  
telephon commented 4 years ago

Later in the performance superdirt struggles a bit with high polyphony vs the stream capture.. Is there a setting to limit polyphony? (Either by stopping oldest sounds or not playing the newest one)

I've just added a simple way to protect a performance from overloading.

It's something to be hand-tuned for now, I think. This is how you can do it:

~dirt.dropWhen = { ~dirt.server.statusWatcher.peakCPU > 3.3 }; // limit to 3.3 % cpu

The statusWatcher also has various information that can be used for tuning:

var <numUGens=0, <numSynths=0, <numGroups=0, <numSynthDefs=0;
var <avgCPU, <peakCPU;

let me know how it goes. Maybe we should post this in the club?

yaxu commented 4 years ago

@lwlsn do you have some time to try this?

telephon commented 4 years ago

I've added a script that explains it a little:

https://github.com/musikinformatik/SuperDirt/blob/7589ccc3f5b780f07de869bb976677cf5af2a8e8/scripts/safety-limits.scd

lwlsn commented 4 years ago

sure ! I'll test it out now

lwlsn commented 4 years ago

So I updated my SuperDirt to the most recent version and there are no more problems with an overloaded low pass filter of frequency >20kHz.

I also tested out the ~dirt.dropWhen function by running locally in SC and that seems to stop the problem that happened in performance when Peak CPU goes over ~90. Perhaps it should be added to SuperDirt as a default setting?

telephon commented 4 years ago

So I updated my SuperDirt to the most recent version and there are no more problems with an overloaded low pass filter of frequency >20kHz.

ah good – I think the protection has been in there for a longer time, you must have had an older version.

I also tested out the ~dirt.dropWhen function by running locally in SC and that seems to stop the problem that happened in performance when Peak CPU goes over ~90. Perhaps it should be added to SuperDirt as a default setting?

Thank you for testing it. I agree that it is better to drop synths than to get the system into an overloaded state. Maybe we can fine tune it first and see what is the best setting? And then we add it as a default.

telephon commented 4 years ago

perhaps we don't even need that completely customisable dropWhen function, but we can just set a cpu limit (saves a bit of calculation).

telephon commented 4 years ago

I just realised that it may also happen that you don't hit the limit of scsynth but of sclang. But to get the cpu usage of sclang, currently, we have to call a system cmd, like:

unixCmdGetStdOut("top -l 1 -pid" + thisProcess.pid);

or on linux:

unixCmdGetStdOut("top -bn1 -pid" + thisProcess.pid);

This operation is quite slow, so nothing we want to do all the time.