Skip to content
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

TinySoundFont fails to render a specific combination of .sf2 and .mid #46

Open
TerminX opened this issue Mar 19, 2020 · 11 comments
Open

Comments

@TerminX
Copy link

TerminX commented Mar 19, 2020

Here are the files we're having trouble with: tsfbug.zip

We were able to get that particular .sf2 working by clamping the sustain in tsf_region_envtosecs() and clamping region->attenuation where voice->noteGainDB is calculated in tsf_note_on(), but we were hoping to ditch the hacky workaround for a real fix since you were so responsive to the previous issue I reported.

Thanks in advance for taking a look at it and for a great single-file library.

schellingb added a commit that referenced this issue Mar 19, 2020
@schellingb
Copy link
Owner

Hi again

So this soundfont sets an attenuation value of -997.5 while the value should be between 0 and 1440. The fix I committed clamps the value which makes it play nice.
Hopefully that was all that was wrong, it sounds ok to me.
Now, TSF only clamps a few of the incoming values to their legal ranges. It probably should have a full table of min and max values for all generators and have a generic way of limiting them all instead of just special handling like the one I added now. Hopefully that can be added in the future :-)

Thanks again for testing and reporting.

@TerminX
Copy link
Author

TerminX commented Mar 20, 2020

Well, it's improved, but still broken... you have to listen to about the halfway point before things really screw up, though. The commit you made does make the hack we had to clamp region->attenuation in tsf_note_on() unnecessary, but we're still needing to clamp the sustain value in tsf_region_envtosecs() to get the file to play correctly.

Do you think that maybe the .sf2 is out of spec in this way as well, or maybe stuff like FluidSynth uses out of range values in these fields in some way as extensions to the format? The file does work in applications using FluidSynth but I don't know if that's because the values indicate something or if it's just clamping the ranges upon load and whoever created the .sf2 made some mistakes.

schellingb added a commit that referenced this issue Mar 20, 2020
@schellingb
Copy link
Owner

Ok, so there were some more values out of range which needed clamping.
Soundfont regions are summed up from global zone, preset zone and instrument zone, so it's easy to end up with values outside of the range (either intended or unintended).
So now we're clamping all values to the range according to the SF2 spec. And we even made the output binary 1K smaller. Magic!
I think this is what Fluidsynth is doing as well. Their code is unreadable though so I'm not exactly sure.
Looking forward to your listening results :-)
Thanks again.

@TerminX
Copy link
Author

TerminX commented Mar 20, 2020

That seems to have fixed the problem! Actually, I think most of the .sf2 files I've been testing with sound better now in ways that are hard to describe, even stuff like old 4MB Creative banks. It really seems like a marked improvement. Thank you so much for the quick fixes.

@schellingb
Copy link
Owner

Happy to hear!
When making this last update, I added a printf to the places where we're now clamping values and for some sf2 files it's quite a lot. Most of the clamps are only minor adjustments but I think TinySoundFont made a huge compatibility step with this.
Good thing that the initial fix wasn't enough :-)

@TerminX
Copy link
Author

TerminX commented Mar 21, 2020

Hey, I've got another .sf2 that blows up. ;) I'm sorry!
Turtle Beach Montego II Aureal GM.zip

schellingb added a commit that referenced this issue Mar 21, 2020
Sometimes in voice rendering an unset temporary variable could be used
Related to #46
@schellingb
Copy link
Owner

Mmh, that was embarrassing... thanks for pointing that out!
I assume many presets of many soundfonts were quite broken because of the failed "optimization" I sneaked into that previous commit.

With that fixed, I still feel like the fourth channel (Sawtooth Lead) is a bit loud, especially after the 35s mark. At least compared to the output of XMPlay's xmp-midi which sounds nicer to me (softer sawtooth lead). The calculation of midi channel volumes was always a bit of a mystery to me so I'm not sure if it's a problem with midi volume or with the soundfont parsing/rendering.

@TerminX
Copy link
Author

TerminX commented Mar 21, 2020

It does sound a bit loud. Say, have you ever seen this post: https://musescore.org/en/node/71881 ? It could be relevant here.

@schellingb
Copy link
Owner

That post might seem relevant, not sure. Sadly the sample prepared by that poster are not for download anymore (the link somehow contains something different now).
I think what I would like to do, is to generate a midi that plays either a single note or a chord of that Sawtooth Lead preset at a velocity 80 (like in GRABBAG.MID at the 34 second mark).
Then we could render out test WAVs from Fluidsynth/BassMidi(XMPlay)/TSF of both the MIDI and directly playing the note (without going through MIDI) to find out if the problem is in the handling of MIDI volume/expression or if it is an issue how the SF2 itself is parsed. And go from there.

@schellingb
Copy link
Owner

Looking at the SF2 file some more, I realize that "Turtle Beach Montego II Aureal GM" uses custom modulators. For instance "Sawtooth Lead" instruments use a modulator which influences the attenuation (volume) depending on the pressed note key. Modulators are not supported by TSF and I have no plans of implementing them as their specs are quite big.

@StrikerMan780
Copy link

I wonder if it's possible to at least implement some of the modulator effects/opcodes used by the most commonly used soundfonts? Arachno comes to mind.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants