Zerberus features & fixes needed for upcoming percussion library

• Apr 24, 2018 - 15:59
Reported version
2.2
Type
Functional
Severity
S5 - Suggestion
Status
closed
Project

While developing the new SFZ percussion library for MuseScore, I have run across a number of shortcomings in Zerberus that we will need to fix before we can release this library. Everything mentioned in this report can be tested using the attached project file. Instructions:

  1. Download the attached test file.
  2. Copy the .sfz file and sample folder to MuseScore's SoundFont directory.
  3. Load the test .mscz file into MuseScore.
  4. Go to "View" -> "Synthesizer" and click "Load from Score" to load the samples.
  5. Play the project. WARNING! The third test can get quite loud, so be ready to turn down the volume.

Here is what needs to be addressed:

Add Support for the Following Opcodes

delay= [0 to 100 seconds]

Description: Region delay time, in seconds. If a delay value is specified, the region playback will be postponed for the specified time. If the region receives a note-off message before delay time, the region won't play, unless the loop mode for the region is set to "one_shot". All envelope generators delay stage will start counting after region delay time.

Comments: This opcode is necessary to create a realistic ensemble effect out of solo samples.

pan= [-100 to 100]

Description: The panoramic position for the region, in percent. If a mono sample is used, pan value defines the position in the stereo image where the sample will be placed. When a stereo sample is used, the pan value defines the relative amplitude of one channel in respect to the other. A value of zero means centered, negative values move the panoramic to the left, positive to the right.

Comments: Stereo positioning is necessary for even the most basic sound design. I was surprised that Zerberus doesn't support this. In addition to "pan", the "width" and "position" opcodes should ideally be supported as well. More info regarding SFZ stereo positioning can be found here: http://www.drealm.info/sfz/plj-sfz.xhtml#stereo

offset= [0 to 4294967296]

Description: The offset used to play the sample, in sample units. The player will reproduce samples starting with the very first sample in the file, unless "offset" is specified. It will start playing the file at the "offset" sample in this case.

Comments: This opcode is needed for simulating release samples and section rolls.

group_volume= [-144 to 6 dB]

Description: The volume for the group, in dB.

Comments: This opcode is unique to the ARIA engine, but in my opinion should be implemented by other SFZ players as well. The "group_volume" opcode will adjust the volume of an entire group at once, which is especially useful in cases where the "volume" opcode is being used to adjust individual sample balance within the group. Here is a brief example to show why "group_volume" is desirable:

Observe the following SFZ code:

<group>
<region> sample=1.wav
<region> sample=2.wav
<region> sample=3.wav volume=-2
<region> sample=4.wav

You can see that sample "3.wav" has been attenuated by 2 dB. Now, let's say that I later determine that the entire group is too loud and I want to reduce the entire group -6 dB in volume. If I add the opcode "volume=-6" to , the actual result would be that samples 1,2 and 4 would now be playing at -6 dB, but sample 3 would still be playing at -2 dB, making it now louder than the rest of the group. I would have to manually change sample 3 to "volume=-8" to keep it 2 dB quieter than the rest of the group. In this example, such an adjustment is trivial, but in more complex groups, it can be a lot of work, especially if the SFZ author has to test different group attenuation values to find the right one.

This is why the "group_volume" opcode exists. If I use "group_volume=-6" in instead, then every sample is adjusted down 6 dB from where it is individually set to be. So, in this example, samples 1,2 and 4 would now be playing at -6 dB and sample 3 would be playing at -8 dB.

filters (fil_type=, cutoff=, etc.)

It appears that filters are currently not implemented at all in Zerberus. Adding support for filters (lowpass, highpass, 1 pole, 2 pole, etc.), filter envelopes and velocity tracking would be a nice addition that would allow us to create more realistic changes in an instrument's tone as the dynamic level changes. Without support for filters, quiet drum hits will sound identical to the loud hits, just quieter.

Bugs

For the bugs, I have created individual bug reports, linked here:
1. Bug #271719: zerberus: repeated release samples play louder and louder until everything is a distorted mess. If a "trigger=release" region is still playing when a second instance of the same region is triggered, the second instance will play louder than the first. If further instances continue to be triggered in a similar manner, subsequent samples will play progressively louder until you are left with a distorted mess.
2. Bug #271722: zerberus: long release samples do not play in their entirety. Release samples only play for about 3 seconds then quit.
3. Bug #271718: zerberus: frequent clicking noises when playing samples.

Attachment Size
Zerberus_test_01.zip 427.27 KB

Comments

Chris, could you please specify the exact minimal (must have) and desired (nice to have) lists of filters you want to see in 2.3?

FYI, I've implemented offset, delay and pan in MuseScore, but the code in a state of pull request. I hope (realistically) to finish the development of opcodes by the end of next week and fixing the mentioned bugs by the end of the first week in June.

The following filters are needed for the new percussion library:
lpf_1p
lpf_2p
hpf_1p
hpf_2p

I am not using the resonance feature, and probably won't need to. Also, do you know if custom/alternate curves are supported in Zerberus? The README file wasn't clear on this.

Chris, I need test file with the mentioned filter opcodes required for percussion library. Could you please attach the .sfz and .mscz if possible?

Status (old) active fixed
Status active fixed

Fixed in branch 2.3, commit 2c816de49e

fix #271723: support for opcodes required for percussion library

delay, pan (there is a bug - effects are applied despite on pan mixing
channels), offset, group_volume support

Fixed in branch master, commit 5c7c5f4148

fix #271723: support for opcodes required for percussion library

delay, pan (there is a bug - effects are applied despite on pan mixing
channels), offset, group_volume support

In reply to by Anatoly-os

Attached is a test for the filter opcodes. Page 1 of the MuseScore file runs the tests through Zerberus, and page 2 plays reference recordings of the same tests rendered using Plogue Sforzando. Instructions for loading the samples are included at the top of page 1 in the MuseScore file.

It is not necessary that Zerberus be able to pass tests #5 (custom curve for filter velocity tracking) and #7 (filter resonance), but I wanted to test for those features in case they were added. They would be useful features to have for the future, but are not critical for the percussion library. The remaining tests should cover all of the filter functionality that will be needed for now.

Attachment Size
Zerberus_filter_test_01.zip 542.64 KB
Status (old) patch (code needs review) fixed
Status fixed

Fixed in branch master, commit 6c24484408

fix #271723: implement filters in Zerberus

Implement cutoff, fil_veltrack, fil_type (lpf_2p and hpf_2p).

Status (old) fixed active
Status fixed active

More filters are going to be implemented, lpf_1p and hpf_1p in particular and maybe bpf_2p and brf_2p.

Status (old) active fixed
Status active fixed

Fixed in branch 2.3, commit 72272425bd

fix #271723: implement filters in Zerberus

Implement bpf_2p, brf_2p, lpf_1p and hpf_1p filters.
Make refactoring: extract filter logic to separate class, make voice class simpler and easier. Optimize and fix code in applying filters.

Fixed in branch master, commit ebb5e9c15f

fix #271723: implement filters in Zerberus

Implement bpf_2p, brf_2p, lpf_1p and hpf_1p filters.
Make refactoring: extract filter logic to separate class, make voice class simpler and easier. Optimize and fix code in applying filters.