-
Notifications
You must be signed in to change notification settings - Fork 267
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
filter cutoff and Q NRPNs don't behave correctly #1473
Comments
I started looking into this. Thanks for the excellent write-up and test suite! Before I go into details:
Should be I started some changes on the Tests 5 & 6 were pretty simple to solve. Tests 1 & 2 have been solved as well - however, the shape is still different. That's because the AWE32 documentation reports the
I.e. the unit is in Hertz, not in cents. Hence according to the documentation, this should behave linear on the Hertz. I admit this doesn't really make sense, because you get pretty poor resolution in for low frequencies, and almost no change for high frequencies. I'm open to change this to cents scaling to make it behave logarithmic on the Hertz scale. I am struggling with Tests 3 & 4. That's because while NRPN allows to directly specify the filter cutoff, it doesn't allow to specify the filter resonance. I.e. it only allows you to specify a "resonance coefficient" and the filter Q should then be derived through some magic with this table:
This has two implications:
Hence, I assume Q is derived from whatever filter cutoff frequency is currently set. This is also why I believe one cannot use modulators for this logic (one would have to dynamically adjust the amount of the filter_fc modulator, depending on which resonance coefficient has been set). So, in order to get a clue, we would need an additional test cases.
I'm not sure if tests 9&10 would be required. I was hoping they would answer whether the filter's resonance really is higher for lower cutoffs. I can't quite tell it from the filter sweeps in tests 5&6. Let me know if I'm missing something. |
Whoops! That will be fixed in the next update to the test documentation.
Without being able to test an AWE32, there will be no way to compare its behavior with the Audigy. I agree that cents scaling makes the most sense, and I would guess that Creative Labs agreed as well when they programmed the SoundFont 2.01-compliant cards to behave logarithmically. Seeing as (A) FluidSynth is aiming to be an ideal implementation of the SoundFont 2.01/2.04 spec and (B) we do not have access to an AWE32 to test (AFAIK), my vote would be to replicate what the SoundFont 2.01/2.04 compliant hardware is doing.
My understanding is this: the coefficient table is tied to the unique design and limitations of the EMU8000 filter. Some—if not all—of these quirks are also present in later Sound Blaster cards. For example, all Sound Blaster SoundFont synths have the filter being fully open at around 8,000 Hz, as that was the original max filter cutoff on the AWE32. The first published SoundFont specification (2.01) says nothing about these quirks, instead in section 9.1.3 stating, "Because there is tremendous variation within the industry as to filter implementations, this filter is idealized rather than being specified as a particular realization." Measurements from my Audigy2 show that the filter is always more resonant at low frequencies than high, even when there is no resonance specified at all. This seems to line up with the behavior suggested by the coefficient table. You can see this added resonance at low frequencies quite clearly in the Audigy2's filter measurements analyzed in my sampler filter comparison video from a couple years ago. (Please note that since this video was published, BASSMIDI now defaults to the same filter model as FluidSynth, only activating the "quirky" filter when "Enable Sound Blaster Limits" is enabled.) You can also see this in the spectrogram view of test 6 in my original post, where the frequency presence at the cutoff point of the sweep always appears brighter for the Audigy2 than for FluidSynth between 100 and around 2,000 Hz. Assuming this is the same frequency-dependent filter emphasis differential laid out in the coefficient table, it would appear that the quirks revealed in the coefficient table are not just used by the filter Q NRPN, but apply to any use of filter Q. Thus, filter Q values set within an instrument or preset may also be limited in resolution and behavior to this table, though the 16-step resolution would be mapped to around 0–20 dB or so for instrument/preset Q values. (It's hard to tell at which dB value the Sound Blaster's filter Q parameter becomes capped, but it seems to be around 20-24 dB before there is no further change.) Interestingly, examples of limited resolution can be seen in some of the other SoundFont parameters when actually measured from a Sound Blaster card. The Sound Blaster's envelope hold phase has a particularly poor resolution, which I've been able to roughly measure as follows (in seconds):
...etc. It's possible that all envelope phases have similar limits, though if so, attack, decay and release might have their resolution weighted (e.g., high resolution at short times, low resolution at longer times, where inaccuracy is not noticeable). It's hard to say for sure without gruelling testing. Either way, I don't think FluidSynth should be trying to emulate these hardware resolution limitations.
Test 9 & 10 wouldn't be required, as it is already possible to see that the differential resonance levels already exist with both NRPN and non-NRPN use on the Audigy. So, at this point, we have the following factors affecting the filter Q NRPN:
How important is any of this if FluidSynth is aiming to implement the ideal second-order lowpass filter as described in the spec? To the above factors:
I can say with great confidence that if you were to implement the NRPN behavior based on the modulators I proposed, the result would match the Audigy quite well, with the only audible differences being those that already impact the sound due to the differences in filter implementation between Sound Blaster and FluidSynth. If FluidSynth wishes to be able to emulate the EMU8000 filter, that would require the development a whole new filter model. If that were to happen, I would strongly suggest it not replace the current filter model but exist as a separate option (similar to how BASSMIDI currently does it). |
Alright Christian, you're very convincing as usual :) I'll ditch all the mentioned filter-implementation-quirks from the NRPN implementation and just go ahead with the modulator approach you've suggested. Doing so might also give me an opportunity to come up with a solution that would somehow fit to the request in #1420. I guess finding a good place to override the initial filter Q and fc with the values you provided and injecting the special NPRN modulators instead will become the most tricky part. |
FluidSynth version
2.4.2
Details
Control of filter cutoff and resonance (Q) via NRPNs was introduced with the AWE32 and continued to be supported in all later Sound Blaster cards containing a hardware SoundFont synth, as far as I am aware. Recent versions of FluidSynth now support these NRPNs, but its behavior is not correct when compared to my Sound Blaster Audigy2 ZS, and likely not accurate to the original AWE32 either.
As for defining the "correct" behavior of these NRPNs, one must decide which of Creative's sound cards to model. I believe FluidSynth should model the behavior of the later, SoundFont 2.01–2.04 devices such as the Audigy for the following reasons:
Test Results
I have created a filter NRPN test. It contains a
recordings
folder in which you can compare recordings of the test run on FluidSynth 2.4.2 and Audigy2 ZS. Through this, we can see several differences between the two synthesizers.I will list each test from the accompanying README, along with my notes on the results of both FluidSynth and Audigy2 ZS. The tests are arranged into pairs, with the first of each pair testing NRPN behavior and the second emulating that behavior using a modulator.
Tests #1 & #2
Test #1: If the AWE32 FC NRPN is implemented, you should hear a filter sweep from 100 to 8000 Hz and then back down to 100 Hz.
Test #2: You will hear a filter sweep that emulates the AWE32 FC NRPN filter curve via CC1 modulator.
Here is a spectrogram view of tests #1 (left) and #2 (right) between Audigy2 (top) and FluidSynth (bottom):

Tests #3 & #4
Test #3: You should hear a sustained white noise wave while the filter switches every two seconds through the following values: 0 (100 Hz), 13 (157 Hz), 25 (237 Hz), 38 (371 Hz), 51 (581 Hz), 64 (910 Hz), 76 (1377 Hz), 89 (2156 Hz), 102 (3376 Hz), 114 (5108 Hz), 127 (8000 Hz). Each jump in the filter should sound roughly like the interval of a fifth.
Test #4: The same as the above test, but with the AWE32 FC NRPN filter curve emulated via CC1 modulator.
Here is a spectrogram view of tests #3 (left) and #4 (right) between Audigy2 (top) and FluidSynth (bottom):

Tests #5 & #6
Test #5: You should hear a series of filter sweeps, each with progressively higher filter Q: 0 (0 dB), 13 (2.03 dB), 25 (3.91 dB), 38 (5.94 dB), 51 (7.97 dB), 64 (10 dB), 76 (11.88 dB), 89 (13.91 dB), 102 (15.94 dB), 114 (17.81 dB), 127 (19.84 dB)
Test #6: The same as the above test, but with the AWE32 filter Q NRPN emulated via CC2 modulator.
Here is a spectrogram view of test #5 between Audigy2 (top) and FluidSynth (bottom):

Here is a spectrogram view of test #6 between Audigy2 (top) and FluidSynth (bottom):

Solution
As you can see from the tests results above, the Audigy's filter NRPN implementation can be easily emulated using modulators. This should provide a convenient mechanism for correcting the NRPN behavior in FluidSynth.
To emulate the Audigy's filter cutoff NRPN for a voice:
To emulate the Audigy's filter Q NRPN for a voice:
In addition to getting the curves right, the filter cutoff and filter Q NRPNs should act independently. Activating the filter cutoff NRPN should have no affect on filter Q, and vice versa, but currently FluidSynth (A) overrides filter Q whenever the filter cutoff NRPN is used, and (B) doesn't respond to the filter Q NRPN independently of the filter cutoff NRPN—at least in these tests.
The text was updated successfully, but these errors were encountered: