Regression: Fluid: Envelopes are not behaving correctly

• Jan 31, 2018 - 18:51
Reported version
2.2
Type
Functional
Severity
S3 - Major
Status
closed
Project

In July 2016, pull #2638 was made to make Fluid use sample-based volume. Unfortunately, this commit introduced the following issues:

1. Amplitude envelope broken when envelope delay phase is longer than 0.010 seconds.
If a note has an amplitude envelope delay of longer than 0.010 seconds, the note simply won’t play at all.

2. Some notes cause a loud popping noise (bug #197131).
This bug is triggered by samples in instruments that have the following in common:
1. Low initial filter cutoff (usually around 100-400 Hz)
2. Modulation envelope to cutoff set to high value (e.g. 6000).
3. Modulation envelope has fast attack (0.001 sec.).

In the FluidGM "Synth Bass 1" preset, this technique is used to give the sawtooth wave sample a "bowwww" sound. This is also the method I used in the GeneralUser GS "Synth Bass 1", which also triggers this bug, as does the low C kick drum in the standard drum kit. Demo video here.

Upon examining recorded audio of this phenomenon, it appears that the pop is caused by the amplitude and modulation envelopes occasionally being out of sync with each other i.e, the amplitude envelope starts note playback before the modulation envelope has added its amount to the filter cutoff. When this amount is added late, it causes an audible pop in the sound.

Lasconic attempted to fix this with pull #3234 (Fix #197131: Regression: Bass synthesizer and bass guitar create popping sounds). Unfortunately, this fix also broke the modulation envelope in some strange ways. Using slower delay and/or attack values causes odd behavior, including incorrect time spent in each envelope phase and/or failure to complete the remaining envelope phases altogether.

I have attached a MuseScore project and accompanying SoundFont that can be used to test both the amplitude and modulation envelopes' functionality. The tests on page 1 of the project will play through MuseScore's internal Fluid synthesizer, and the tests on page 2 will play reference recordings made using upstream FluidSynth. We need to fix Fluid so that the tests on page 1 match those on page 2.

Each test consists of a sustained sawtooth waveform played with each envelope phase lasting exactly 1 second. The sustain phase level is set to 50%. The first test begins with a test tone to signal the start of the delay phase.

The test results for current MuseScore 2.2 devel (9f3cc2c):
Test 1: Amplitude Envelope Test - All Phases - FAIL: The test tone sounds the start of the delay phase, but the sustained tone never sounds.

Test 2: Amplitude Envelope Test - No Delay Phase - PASS: With the delay set to 0.001 sec., the remaining phases of the envelope play correctly.

Test 3: Modulation Envelope Test - All Phases - FAIL: The delay phase plays for only half a second (should be 1 sec.). The attack phase also plays for only half a second (should also be 1 sec.), and doesn't make it up the entire octave. The remaining phases of the envelope fail to play until release.

Test 4: Modulation Envelope Test - No Delay Phase - FAIL: The attack phase plays for only half a second, and the remaining phases fail to play until release.

I am marking this bug as major since it greatly affects my ability to create a high quality instrument bank for the next release.

Attachment Size
Fluid Envelope Test 1.zip 1.54 MB

Comments

In reply to by Nicolas

The envelopes in the earlier revision (8646f2f) do work correctly, with the trade-off that note attacks are a bit "squishy" compared to the sample-based envelope. How noticeable this is depends on the sample, but it is most clearly evident on percussive sounds such as drums and piano.

At the very least, we need to reevaluate the fix for the "popping" noise that affects some instruments, because that fix is what wrecks the modulation envelope (see the GeneralUser GS "Harpsichord" for a good example).

It would be really nice if hpfmn could have a look at this. Would setting the modulation envelope to sample-based clear up the popping issues.

Hi lacsonic, I tested your pull request, and while it does fix the envelope issues, I found the resulting squishy note attacks really sounded bad with percussive instruments. I decided to have a look at the code and discovered a way to fix the popping noises once and for all without breaking the modulation envelope. This way we can have all the benefits of the sample-based envelope without all the breakage :)

The popping was caused by the buffer-based modulation envelope being out of sync with the sample-accurate volume envelope. My fix works by skipping the mod envelope delay and attack phases if they are each less than 100 samples long, ensuring that the envelope will begin at max value synchronous with the start of the note.

Sticking with the sample-accurate volume envelope means that the volume delay phase still doesn't work, but this is easy to work around in my programming. Usually only certain synth instruments use the delay parameter at all, so this will have little affect on my work to create new instruments.

The attached patch includes the fix (line 300 in "voice.cpp") along with all of the white space cleanup that you had incorporated into your pull request. The patches are to be applied against git master.

Attachment Size
mod envelope fix.zip 6.76 KB
Status (old) patch (ready to commit) fixed
Status PR created fixed

Fixed in branch 2.2, commit fc68adf63b

fix #268991: Regression: Fluid: Envelopes are not behaving correctly. Workaround: skip mod envelope delay and attack phases if they are each less than 100 samples long

Fixed in branch master, commit e2f7758103

Merge pull request #3482 from lasconic/fix-268991-cc-master

fix #268991: Regression: Fluid: Envelopes are not behaving correctly. Workaround: skip mod envelope delay and attack phases if they are each less than 100 samples long