qiemem / eurorack

Firmware customization for Mutable Instruments' Eurorack Modules.
93 stars 16 forks source link

LFOs, especially clocked one, can cause and suffer from performance issues #9

Closed qiemem closed 3 years ago

qiemem commented 3 years ago

To reproduce:

Bisecting blames this commit, which added the linear restoration to controls after locking: https://github.com/qiemem/eurorack/commit/3f39a7dc827c6f4927fc0a3c95177ff2a25500ba

That code path doesn't directly influence the clocked stuff. I think it + 6 LFOs running are just computationally intensive enough that it pushes the module over the edge and it can't keep up. I'll probably just toss the limbo stuff to fix.

qiemem commented 3 years ago

Playing with this more, you can really mess things up by clocking more LFOs. 2 clocked will start to mess up unrelated, non-clocked LFOs.

TBH it sounds kind of awesome and I kind of don't want to fix it...

It does however basically kill any use as a Trautonium.

qiemem commented 3 years ago

Short circuiting the limbo check with a slider_limbo_ improves it (can do 3 clocked and 3 non-clocked); just as good as eliminating limbo altogether. So good news is limbo can stay. Bad news but actually good news is that it's time for general performance optimization.

qiemem commented 3 years ago

A good best test for this:

Stock has no problem with running all six this way. With local fixes, I can get up to 4.

Use non-audio-rate as the audio-rate PLL algorithm is faster.

Edit:

Easy way is to just set all six segments to be square-wave LFOs with frequency in the middle. Then plug 5 into the gate of 6, 4 into the gate of 5, etc. Problems are extremely obvious here, as a deviation anywhere will cause compound problems down the chain. Stock can get all six clocked and blinking in unison. Current build can do 3 clocked. Found that the addition of attenuating segments caused a big hit.

qiemem commented 3 years ago

Discovered this was being complicated by the fact that one of my 6 inch patches was bad...

qiemem commented 3 years ago

sigh Another complication: Even on stock, for segments 4 & 5, a downward ramp into the gate will sometimes trigger twice. This happens no matter what the segment type is. Easy to see on decay segment or gate generator. It appears to only affect segments 4 & 5 on both of my Stages.

qiemem commented 3 years ago

So, after controlling for the factors described above and bisecting again, I can definitively say that c2ec3b921300c45ad80d5419bcc6a8d3bd038030 introduced this problem, which is good news in some sense (as opposed to the problem being introduced by a bunch of little things over time). So I need to rethink the switching to audio-rate clocked LFOs.

Reverting ramp_extractor to official/master removes the majority of the problem for low-frequency clocked LFOs. There seems to be a little bit of oddness for audio-rate still, but hard to tell since it is using the original (non-audio-rate) algorithm, and with all 6 clocked LFOs, the last segment can get a little weird.

qiemem commented 3 years ago

I've been able to consistently get 4 clocked LFOs by having on_duration computed when the gate falls rather than incremented while high.

I tried getting rid of the if (audio_rate_) branch by having both algorithms loop in whiles until a rising gate was received, at which point they would break out to the pulse recording code. Unfortunately, I couldn't get it working and it didn't really seem to help. There's variations of this I could try, but honestly, they're a pain to get right with the ordering of pointer updates and such.

qiemem commented 3 years ago

395a04255882f196435e1515770c8f3bbcdd0a28, 49f6f0ad6cd5dd1c67a625309a44b16fa0da7ef6, and 1fef1495c9d46c2904283d63029fa560b74eaf8f improve this immensely. 6 clocked audio rate lfos now work without artifacts, and 5 lfo + 1 audio rate work with occasional pops and clicks. I'm going to call this good enough.