View Ticket
Not logged in
Ticket UUID: 47b8981ade9a7631a7340d1b3c7cec720f539903
Title: Preset numbers are not preserved
Status: Closed Type: Code_Defect
Severity: Critical Priority: Immediate
Subsystem: Resolution: Fixed
Last Modified: 2014-11-22 22:32:45
Version Found In: d0f178c2c0e9c7c7
User Comments:
anonymous added on 2014-11-19 15:23:03:
When the presets in a soundfont are not numbered contiguously starting at 0, their preset numbers (as stored in the wPreset field) are lost in the conversion to XML.

For example, if a .sf2 file containing two presets with preset numbers 24 and 25 is converted to xml and back to .sf2, the two presets will now have preset numbers 0 and 1.

Suggested fix:

diff --git a/pysf.py b/pysf.py
index a83c117..edce72e 100755
--- a/pysf.py
+++ b/pysf.py
@@ -627,6 +627,7 @@ def SfZoneList(Tree, Zt):
     AchName = 'ZORKMID'
     WBagNdx = -999
     WBank = -999
+    WPreset = -999
     Order = 0
     Bag = Tree.CkId(Zt.Bag, None, -1)
     if Bag == None:
@@ -655,6 +656,7 @@ def SfZoneList(Tree, Zt):
         LastAchName = AchName
         LastWBagNdx = WBagNdx
         LastWBank = WBank
+        LastWPreset = WPreset
         if Zt.KeyN == 'instrument':
             (
                 AchName,
@@ -674,12 +676,14 @@ def SfZoneList(Tree, Zt):
         HdrD = HdrD[HdrFmtLen:]
         if Order > 0:
             IPDict = {
-                u'id': Order,
                 u'name': LastAchName,
                 u'zones': {}
             }
             if Zt.KeyN == 'preset':
                 IPDict[u'bank'] = LastWBank
+                IPDict[u'id'] = LastWPreset
+            else:
+                IPDict[u'id'] = Order
             ZList = []
             for I in range(LastWBagNdx, WBagNdx):
                 Base = I * BagRecLen
@@ -1110,6 +1114,7 @@ def SfZone(Dict, Zt):
         Name = SfStr(Def(Val(InPr, u'name'), ''), 20)
         if Zt.KeyN == 'preset':
             WBank = Def(Val(InPr, u'bank'), 0)
+            WPreset = Def(Val(InPr, u'id'), 0)
         ZoneIndex = 0
         if len(InPr[u'zones'][u'zone']) == 0:
             GenD = GenD + struct.pack('<HH', 60, 0)
@@ -1246,7 +1251,6 @@ def SfZone(Dict, Zt):
         if Zt.KeyN == 'instrument':
             HdrD = HdrD + struct.pack('<20sH', Name, LastNBag)
         elif Zt.KeyN == 'preset':
-            WPreset = HdrC
             HdrD = HdrD + struct.pack(
                 '<20sHHHIII',
                 Name,

bencollver added on 2014-11-22 22:32:45:
Thank you for the bug report and fix!  -Ben