layered sf2 files play weirdly

Issue #58 new
1234ab created an issue

Hi! This is amazing! I was trying out different soundfonts and midis I have, and there is a problem with this combination, and with similar ones too (attached).
The volume is supposed to be like this: https://musescore.com/xeoran/wynncraft---luxury-of-the-cease-fire-ragni

but some notes are much louder than the others. There were also some instruments that were off.

I think it might be because the soundfont has different samples for the different piano volumes, but I don’t know much about sf2 files.

I tried it with A320U.sf2 and it works as intended there, so the incompatibility is with the soundfont, not with the midi file.

Comments (10)

  1. きのもと結衣 repo owner

    The Soundfont(sf2) has wave, volume and pitch or something, Godot MIDI Player uses these data without convert.
    probably Soundfont has wrong volume/pitch data, I think.

    for example, MIDI sequence is C4. but sf2 set wrong pitch. GMP will not play C4 wave.

  2. きのもと結衣 repo owner

    Volume is a very specific problem.
    The soundfont that included bug.zip uses a method of layered many sounds. GMP can't sound exactly the same time (and can't use many sound, max polyphony is default 96 sounds).
    Therefore, the volume will be wrong.

  3. 1234ab reporter

    Thanks for the quick reply! Yeah, I understand that GDscript is probably very limited in this regard, and it’s still amazing that you could make this! For my use case A320U.sf2 or similar simpler sf2 files will be perfect, but oh those more complex sf2 files could sound even better :D.

  4. きのもと結衣 repo owner

    if GDScript has vector calc library like numpy in Python, can be synthesized layer sounds in loading time. lol

    when comes it for 4.x, I will support it.

  5. David Shorten

    Hi,

    I ran into this issue with a different sound font file. I think the issue here is actually that there doesn’t seem to be support for velocity range as a preset generator. The soundfont I am using has a number of instruments, each having samples with a key range configured, and then the preset maps different velocity ranges to each instrument. This means that when the player tries to use the soundfont, it will try to use every instrument for the preset, and you’ll get a bad result. I think this can be resolve by adding support for the velocity range to the sound font bag, e.g., here.

  6. David Shorten

    I was able to make this work for me by doing this:

    diff --git a/addons/midi/Bank.gd b/addons/midi/Bank.gd
    index ccacc1b..26b78c1 100644
    --- a/addons/midi/Bank.gd
    +++ b/addons/midi/Bank.gd
    @@ -58,6 +58,7 @@ class TempSoundFontBag:
         var coarse_tune:int
         var fine_tune:int
         var key_range:TempSoundFontRange
    +    var velocity_range:TempSoundFontRange
         var instrument:TempSoundFontInstrument
         var pan:float = 0.5
    
    @@ -243,6 +244,8 @@ func read_soundfont( sf:SoundFont.SoundFontData, need_program_numbers:Array = []
                             bag.pan = float( gen.amount + 500 ) / 1000.0
                         SoundFont.gen_oper_instrument:
                             bag.instrument = sf_insts[gen.uamount]
    +                    SoundFont.gen_oper_vel_range:
    +                        bag.velocity_range = TempSoundFontRange.new( gen.uamount & 0xFF, gen.uamount >> 8 )
                 if bag.instrument != null:
                     preset.bags.append( bag )
                 gen_index = gen_next
    @@ -464,8 +467,8 @@ func _read_soundfont_preset_compose_sample( sf:SoundFont.SoundFontData, preset:P
                     instrument.volume_db = volume_db
                     instrument.ads_state = ads_state
                     instrument.release_state = release_state
    -                instrument.vel_range_min = vel_range_min
    -                instrument.vel_range_max = vel_range_max
    +                instrument.vel_range_min = max(vel_range_min, pbag.velocity_range.low)
    +                instrument.vel_range_max = min(vel_range_max, pbag.velocity_range.high)
    

    But I’m not entirely convinced that this is the right behavior.

  7. きのもと結衣 repo owner

    @David Shorten I remember that the velocity range did not implemented for reduce memory. I will implement with enable/disable flag.

  8. Log in to comment