-
-
Notifications
You must be signed in to change notification settings - Fork 1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allways remove infs/nans #3706
Allways remove infs/nans #3706
Conversation
The demo project in #3408, envelopeNaN.mmp.zip has some amazing new noise going on with this PR. What happens is probably something like this: Some faults give you infinite values and these propagated through the sound chain will metamorphose into NaN. The NaN will make lmms go silent. |
If you only turn on the Sanitizers in the FX-Mixer the sound will cut out on just the troubled channel and not affect the whole mix. This could be a better option. |
47ac277
to
4e2242c
Compare
Some projects use them as a intermediate signals. If we clip them, some projects may give different sound output. And I have a question: what if an instrument generates NaN and its output goes to master FX channel directly? If there is something like master reverb, the result will be worse. |
Yes. This is a destructive PR in that sense. You could have a switch to allow higher signals. I don't know how many projects would be affected though. It would probably be more user dependent, the ones that has the habit of driving a large signal through the FX channel.
Not worse but equally shitty I think. I've kept an eye open on the master channel but so far I haven't seen it acting up because of this in any way. And I've hit it with NaN intentionally. I'll try and come up with a more angry test... :) |
If this fixes the notorious bug where the mixer from goes silent, this comes with a lot of value. @zonkmachine @PhysSong Can we make a decision on this and merge? |
It does. I think it should be merged and I think perhaps 1.2 is a better target than master. |
A sample file may contain inf/NaN stuffs. In that case, this PR won't help to fix such issues. Anyway, Clipping signal at +/- 1.0f doesn't sound good for me. I think it should be some appropriate larger level(ex. 4.0f~10.0f) for intermediate signals and 1.0f(or slightly larger value) for master FX channel. |
Yes, I started out with 4.0f in the first version I pushed and in testing this 10.0f was about where the glitches would start to be too loud. |
Interesting, I didn't think of this possibility. I went looking for some audio test suites containing various defective sound files for further testing but I couldn't find any. There are |
@zonkmachine I have a .wav file with NaN value. I can provide it if you want. |
Yes please! |
When exporting a project lmms performs extra tests for bad data. The tests are for infs and nans. Switching these tests on for all occasions as the extra performance hit would be in the order of only ~2% and the problems, when it hits the end user, are hard to debug and/or work around.
This will check for infs/nans in between the effect units and will clear up most cases where projects with bad data would simply cut out all sound at one point or be all silent. It comes with a slight performance hit of some 2% more cycles. The down side is that now instead of cutting out at the point of bad data some large signals will get through that could potentially hurt equipment. Resolves: LMMS#1048, LMMS#3685
0f3d284
to
e2c4586
Compare
Changing base for the time being as my master branch isn't anywhere near sane. |
Currently we shut out defunct signal values like inf/nan but we apart from that we allow signals of any size. This will let large but short shot noise through that can trigger especially reverb to dangerously large sound levels even though they would pass largely unnoticed without a feedback loop. After testing for inf/nan we clamp the sound to +/-4.0f .
e2c4586
to
178e342
Compare
Changed to +/-4.0f |
@zonkmachine Here is a .wav file full with NaN. I made it using hex editor. |
Super! Can you fix one with infinites too? :) As you suspected an audio file to Master will sneak past the checks. As will any sound that doesn't have an FX unit in it's path. |
Actually, sound via a mixer channel is catching NaN even without an FX unit. It's only direct to Master that's an issue. |
I guess no one would want to use Infs/NaNs in a creative way. One might use a very loud intermediate signal to do something crazy and break effects in creative ways with that, but invalid float samples could probably be sanitized safely, without hurting creativity. |
But how much louder? What levels do other studios, like Ardour and Bitwig, use for clipping? |
@unfa Here's the thing. The NaN's will cut the sound for a channel or even a whole mix. If you remove nan's/infinites, there will instead be an audible glitch in it's place where the sound is on it's way to/from infinitely high. This needs to be limited or it will give you a wall of noise when the glitch is followed by a reverb unit. Right now the suggested level for limiting is +/-4.0 . I've tried to trigger some of the glitches we've seen with ladspa pluggins in audacity and if they have a limit it seem to be much higher than that and I think we should err on being less generous in lmms. Have you seen any similar glitches in other daw's? Ardour? |
As I've understood it, exporting will clip at +/-1.0 anyway so I think this should be the clipping level. I believe this is the signal level limit for VST's too.
I think this is a separate issue and should probably be fixed in SampleBuffer.cpp |
OK. I made a project with nan2.wav
Without this fix the sound will cut out from when the nan ridden file starts sounding and you need to reload the project or bypass the reverb to get the sound back. With this fix the sound will cut out with the bad sound file playing but it will come back again as soon as the sample is done playing. So, a bit of an improvement but it still needs fixing on the sample side. SampleBuffer.cpp... |
Export issue: https://lmms.io/forum/viewtopic.php?f=7&t=27199 |
I don't have much to offer this because I don't know the DSP code well enough to understand what this will break. My initial concerns were that stuff like C*CLIP would have problems, but it doesn't appear to. I'm sure this is simply a lack of understanding where sanitize is being called. Anyway, I did two tracks with BEFORE and AFTER... In both cases, the tracks play fine. Both tracks make heavy use of effects plugins and to the naked ear, I can't hear a difference. There are slight visual differences, but I believe these are directly attributed to nondeterministic plugins and effects, which will create the differences regardless of this PR. @zonkmachine I think we can merge this, but it would be nice to have a real-world track in the wild to unit-test against (rather than the one that as made intentionally to test this scenario). (I know this is not what unfa-Spoken normally looks like, the track has some playback issues on Mac that are unrelated to this PR) |
We already do this sanitizing but only on export. The only difference you'd see should be:
I'll go about it tomorrow. |
That makes sense. I thought the code was already there for export. Ok, yes, in that case we definitely need to merge this. |
It seems to cause clipping for one of our demo projects, |
I don't know what to look for with this one as it's clipping with or without this PR. I exported as tracks and 11 out of 56 tracks was clipping but the rendered tracks are also clipped in the render process to +/-1.0 so it needs some more probing into which ones go above +/-4.0. |
Edit: A better approach would be checking for Line 201 in fce9326
|
When exporting a project lmms performs extra tests for bad data. The tests are for infs and nans. Switching these tests on for all occasions as the extra performance hit would be in the order of only ~2% and the problems, when it hits the end user, are hard to debug and/or work around. After testing for inf/nan we clamp the sound to +/-4.0f as sometimes you will get large transients passing through (an issue that is currently only present when exporting). Fixes: LMMS#1048
The team is in talks about reverting this INF/NAN sanitization. I tested the example project in this bug report and was unable to reproduce the bug on nightly, however I'm still able to reproduce the bug with the project files from #1048. Some arguments for removal:
So far, no measured evidence of performance loss has been provided. This should be quantified. Furthermore, despite both of these bug reports containing steps to reproduce, there was no attempt by @LostRobotMusic to quantify "plugins that don't even exist". A simple re-testing of #1048 shows that this problem is still very real. I did do a quick look for the problematic plugin. My initial investigation shows Related: #1048 (comment) |
Audacity playhead just freezes with this file loaded, supporting @LostRobotMusic's point about other DAWs not sanitizing. ... however, Audacity also can be recovered by removing the problematic track, whereas LMMS requires a restart. |
That is because I never once made the claim that they don't exist, and implying that I did is blatantly dishonest and deeply unprofessional. It's impossible to prove such a claim without showing every plugin that has ever been made, which obviously cannot be done. Here's what I said in that same message:
I said I would like an example of one of these plugins so it can be used in testing. I never once made the claim that they do not exist, though I did emphasize their overwhelming rarity and the fact that invalid output is solely the fault of the plugin. I also said that if the plugin doesn't work properly in LMMS due to NaN output, it won't work properly in other DAWs either, which is demonstrably true.
This is false, LMMS doesn't require a restart. The issue goes away once all of the offending plugins are removed or disabled, exactly like Audacity. The issue LMMS has to deal with is the fact that these NaNs can "infect" some future plugins in the signal chain, causing them to output NaNs just like the original offending plugin. It's for this reason that reloading the project file is oftentimes necessary. Restarting the entirety of LMMS is not, in any of the situations I've experienced. |
The absence of this bug was used as supporting argument for its removal, quoting (Discord)
... when combined with targeted, speculative statements of performance, these statements often become persuasive in conversation, quoting: (Discord)
Responses in support of this statement, or to #7323, of which this statement takes credit for the idea of:
... ...
Thanks, this drastically speeds up testing. The requested example has been provided. I did try to test this plugin in Audacity but I couldn't recreate the problem, likely due to incorrect parameters. Testing was taking a long time due to constants restarts of LMMS -- I understand now there was a quicker way to test -- while trying to isolate the parameters that cause the NaNs. I won't be dedicating any more time to this myself, but I hope that narrowing down a problematic plugin can help the project decide if it's worthwhile. Removal of this patch would be a detriment to projects which use these buggy plugins. With regards to professionalism (either in Disord or on the bug tracker), I believe this is a conversation for another medium, perhaps Discussions. |
Lv2, swh, Dyson Compressor. Turn release to 0. |
Brief
Testing to switch the inf/nan tests that are performed on export to be 'on' allways.
This seem to work well. For some 2.5% increase in cycles most of the NaN oriented bugs can be transformed from a project cutting out all sound at a specific point or from start, to just a moderate glitch.
I currently lack real test cases to assess this.
Verbose
I split the original PR into two separate commits and added a new one.
2fc1802 Turn on sanitizers in the FX-Mixer. This effectively prevents the whole projects to go silent because of one channel with a bad signal.
a85b02c Turn on sanitizers in the effect chains. This prevents bad data from shutting down the channel. Basically all NaN ( Warning! Will get loud without 47ac277 )
47ac277 As of the previious commit some dangerously large signals can come through the mix.
Fixed. Clamp values to, for the time being, +/-1.0f . I understand introducing hard limiting like this could trigger some but I see no reason to allow overly large signals. Don't other projects perform some form of clipping?
At this level a glitch will propagate through a reverb with long decay more like a distinct tick. A slight performance hit. +~0.2%.
Profiling
Test Project: Skiessi - Onion
Result: ~2.5% is spent in
MixHelpers::sanitize()
andMixHelpers::addSanitizedMultiplied()
routines.fixes #1048 #3685