[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [fluid-dev] Slightly OT: Parsing SF2; duplicate pbag entries?

From: Tom M.
Subject: Re: [fluid-dev] Slightly OT: Parsing SF2; duplicate pbag entries?
Date: Fri, 22 Feb 2019 22:06:24 +0100

> Specifically, I'm seeing pbag entries in valid and playable
> SoundFonts that don't make any sense to me, and I can't seem to find
> an explanation for them in the spec.
> [...]
> Duplicate entries that both point to pgen[0]. Not pgen[0] and pgen[1]
> as I would expect.

IMO it's valid to do this. Section 7.3 of the Spec says:

"Because both the generator and modulator lists are in the same order as the 
preset header and zone lists, these indices will be monotonically increasing 
with increasing preset zones. [...] If the generator or modulator indices are 
non-monotonic [...], the file is structurally defective and should be rejected 
at load time."

A function f is monotonically increasing, if for all x and y such that x <= y 
one has f(x) <= f(y). So, although pointless, specifying bags with the same 
index multiple times does not contradict this monotonic property.

> However, according to the spec, I have to read pbag entries starting at
> the presetBagIndex for each preset. So, when I read pbag[0] and pbag[1]
> as part of interpreting p0, I encounter:
> TRACE com.io7m.jnoisetype.vanilla.NTParsers: [pbag][0] 
NTParsedPresetZone{generatorIndex=0, modulatorIndex=0}
> TRACE com.io7m.jnoisetype.vanilla.NTParsers: [pbag][1] 
NTParsedPresetZone{generatorIndex=0, modulatorIndex=0}
> How do I interpret those presets such that I can correctly link them to
> the instrument definitions?

Section 7.5 says:

"The preset zone’s wGenNdx points to the first generator for that preset 

Unfortunately this section is lacking a sentence like:

"The number of generators present for a preset zone is determined by the 
difference between the next higher preset zone’s wGenNdx and the current 
preset’s wGenNdx."

However the PMOD and PBAG sections have such statement, so the fact that PGEN 
misses this hint is just a minor bug.

In your case this means:

pbag[0] points to genNdx=0, pbag[1] ponits to genNdx=0; 0 - 0 = 0, i.e. 
pbag[0] has zero generators assigned to it.

pbag[1] points to genNdx=0, pbag[2] points to genNdx=2; 2 - 0 = 2, i.e. 
pbag[1] has two generators assigned to it, the first one is pgen[0] 
(keyrange), the second pgen[1] (instrument)

pbag[2] points to genNdx=2, pbag[3] ponits to genNdx=2; 2 - 2 = 0, i.e. 
pbag[2] has zero generators assigned to it.

pbag[3] points to genNdx=2, it is also the last zone, so it just takes all the 
residual generators, i.e. two: the first one is pgen[2] (keyrange), the second 
pgen[3] (instrument)

Hope that helps. Haven't checked whether that corresponds with fluidsynth 
implementation though.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]