12 #include "midi/base.h"
15 static ALuint
read_le32(Reader
*stream
)
18 if(READ(stream
, buf
, 4) != 4)
23 return (buf
[3]<<24) | (buf
[2]<<16) | (buf
[1]<<8) | buf
[0];
25 static ALushort
read_le16(Reader
*stream
)
28 if(READ(stream
, buf
, 2) != 2)
33 return (buf
[1]<<8) | buf
[0];
35 static ALubyte
read_8(Reader
*stream
)
38 if(READ(stream
, buf
, 1) != 1)
45 static void skip(Reader
*stream
, ALuint amt
)
47 while(amt
> 0 && !READERR(stream
))
52 got
= READ(stream
, buf
, minu(sizeof(buf
), amt
));
53 if(got
== 0) READERR(stream
) = 1;
59 typedef struct Generator
{
63 static void Generator_read(Generator
*self
, Reader
*stream
)
65 self
->mGenerator
= read_le16(stream
);
66 self
->mAmount
= read_le16(stream
);
69 static const ALint DefaultGenValue
[60] = {
70 0, /* 0 - startAddrOffset */
71 0, /* 1 - endAddrOffset */
72 0, /* 2 - startloopAddrOffset */
73 0, /* 3 - endloopAddrOffset */
74 0, /* 4 - startAddrCoarseOffset */
75 0, /* 5 - modLfoToPitch */
76 0, /* 6 - vibLfoToPitch */
77 0, /* 7 - modEnvToPitch */
78 13500, /* 8 - initialFilterFc */
79 0, /* 9 - initialFilterQ */
80 0, /* 10 - modLfoToFilterFc */
81 0, /* 11 - modEnvToFilterFc */
82 0, /* 12 - endAddrCoarseOffset */
83 0, /* 13 - modLfoToVolume */
85 0, /* 15 - chorusEffectsSend */
86 0, /* 16 - reverbEffectsSend */
91 -12000, /* 21 - delayModLFO */
92 0, /* 22 - freqModLFO */
93 -12000, /* 23 - delayVibLFO */
94 0, /* 24 - freqVibLFO */
95 -12000, /* 25 - delayModEnv */
96 -12000, /* 26 - attackModEnv */
97 -12000, /* 27 - holdModEnv */
98 -12000, /* 28 - decayModEnv */
99 0, /* 29 - sustainModEnv */
100 -12000, /* 30 - releaseModEnv */
101 0, /* 31 - keynumToModEnvHold */
102 0, /* 32 - keynumToModEnvDecay */
103 -12000, /* 33 - delayVolEnv */
104 -12000, /* 34 - attackVolEnv */
105 -12000, /* 35 - holdVolEnv */
106 -12000, /* 36 - decayVolEnv */
107 0, /* 37 - sustainVolEnv */
108 -12000, /* 38 - releaseVolEnv */
109 0, /* 39 - keynumToVolEnvHold */
110 0, /* 40 - keynumToVolEnvDecay */
113 0, /* 43 - keyRange */
114 0, /* 44 - velRange */
115 0, /* 45 - startloopAddrCoarseOffset */
117 0, /* 47 - velocity */
118 0, /* 48 - initialAttenuation */
120 0, /* 50 - endloopAddrCoarseOffset */
121 0, /* 51 - corseTune */
122 0, /* 52 - fineTune */
124 0, /* 54 - sampleModes */
126 100, /* 56 - scaleTuning */
127 0, /* 57 - exclusiveClass */
128 0, /* 58 - overridingRootKey */
132 typedef struct Modulator
{
139 static void Modulator_read(Modulator
*self
, Reader
*stream
)
141 self
->mSrcOp
= read_le16(stream
);
142 self
->mDstOp
= read_le16(stream
);
143 self
->mAmount
= read_le16(stream
);
144 self
->mAmtSrcOp
= read_le16(stream
);
145 self
->mTransOp
= read_le16(stream
);
148 typedef struct Zone
{
152 static void Zone_read(Zone
*self
, Reader
*stream
)
154 self
->mGenIdx
= read_le16(stream
);
155 self
->mModIdx
= read_le16(stream
);
158 typedef struct PresetHeader
{
160 ALushort mPreset
; /* MIDI program number */
167 static void PresetHeader_read(PresetHeader
*self
, Reader
*stream
)
169 if(READ(stream
, self
->mName
, sizeof(self
->mName
)) != sizeof(self
->mName
))
171 self
->mPreset
= read_le16(stream
);
172 self
->mBank
= read_le16(stream
);
173 self
->mZoneIdx
= read_le16(stream
);
174 self
->mLibrary
= read_le32(stream
);
175 self
->mGenre
= read_le32(stream
);
176 self
->mMorphology
= read_le32(stream
);
179 typedef struct InstrumentHeader
{
183 static void InstrumentHeader_read(InstrumentHeader
*self
, Reader
*stream
)
185 if(READ(stream
, self
->mName
, sizeof(self
->mName
)) != sizeof(self
->mName
))
187 self
->mZoneIdx
= read_le16(stream
);
190 typedef struct SampleHeader
{
191 ALchar mName
[20]; // 20 bytes
197 ALubyte mOriginalKey
;
199 ALushort mSampleLink
;
200 ALushort mSampleType
;
202 static void SampleHeader_read(SampleHeader
*self
, Reader
*stream
)
204 if(READ(stream
, self
->mName
, sizeof(self
->mName
)) != sizeof(self
->mName
))
206 self
->mStart
= read_le32(stream
);
207 self
->mEnd
= read_le32(stream
);
208 self
->mStartloop
= read_le32(stream
);
209 self
->mEndloop
= read_le32(stream
);
210 self
->mSampleRate
= read_le32(stream
);
211 self
->mOriginalKey
= read_8(stream
);
212 self
->mCorrection
= read_8(stream
);
213 self
->mSampleLink
= read_le16(stream
);
214 self
->mSampleType
= read_le16(stream
);
218 typedef struct Soundfont
{
229 InstrumentHeader
*inst
;
243 static void Soundfont_Construct(Soundfont
*self
)
269 static void Soundfont_Destruct(Soundfont
*self
)
305 #define FOURCC(a,b,c,d) (((d)<<24) | ((c)<<16) | ((b)<<8) | (a))
306 #define FOURCCARGS(x) (char)((x)&0xff), (char)(((x)>>8)&0xff), (char)(((x)>>16)&0xff), (char)(((x)>>24)&0xff)
307 typedef struct RiffHdr
{
311 static void RiffHdr_read(RiffHdr
*self
, Reader
*stream
)
313 self
->mCode
= read_le32(stream
);
314 self
->mSize
= read_le32(stream
);
318 typedef struct GenModList
{
328 static void GenModList_Construct(GenModList
*self
)
339 static void GenModList_Destruct(GenModList
*self
)
352 static GenModList
GenModList_clone(const GenModList
*self
)
356 ret
.gens
= malloc(self
->gens_max
* sizeof(ret
.gens
[0]));
357 memcpy(ret
.gens
, self
->gens
, self
->gens_size
* sizeof(ret
.gens
[0]));
358 ret
.gens_size
= self
->gens_size
;
359 ret
.gens_max
= self
->gens_max
;
361 ret
.mods
= malloc(self
->mods_max
* sizeof(ret
.mods
[0]));
362 memcpy(ret
.mods
, self
->mods
, self
->mods_size
* sizeof(ret
.mods
[0]));
363 ret
.mods_size
= self
->mods_size
;
364 ret
.mods_max
= self
->mods_max
;
369 static void GenModList_insertGen(GenModList
*self
, const Generator
*gen
, ALboolean ispreset
)
371 Generator
*i
= self
->gens
;
372 Generator
*end
= i
+ self
->gens_size
;
375 if(i
->mGenerator
== gen
->mGenerator
)
377 i
->mAmount
= gen
->mAmount
;
383 (gen
->mGenerator
== 0 || gen
->mGenerator
== 1 || gen
->mGenerator
== 2 ||
384 gen
->mGenerator
== 3 || gen
->mGenerator
== 4 || gen
->mGenerator
== 12 ||
385 gen
->mGenerator
== 45 || gen
->mGenerator
== 46 || gen
->mGenerator
== 47 ||
386 gen
->mGenerator
== 50 || gen
->mGenerator
== 54 || gen
->mGenerator
== 57 ||
387 gen
->mGenerator
== 58))
390 if(self
->gens_size
== self
->gens_max
)
395 newsize
= (self
->gens_max
? self
->gens_max
<<1 : 1);
396 if(newsize
> self
->gens_max
)
397 temp
= realloc(self
->gens
, newsize
* sizeof(self
->gens
[0]));
400 ERR("Failed to increase generator storage to %d elements (from %d)\n",
401 newsize
, self
->gens_max
);
406 self
->gens_max
= newsize
;
409 self
->gens
[self
->gens_size
] = *gen
;
412 static void GenModList_accumGen(GenModList
*self
, const Generator
*gen
)
414 Generator
*i
= self
->gens
;
415 Generator
*end
= i
+ self
->gens_size
;
418 if(i
->mGenerator
== gen
->mGenerator
)
420 if(gen
->mGenerator
== 43 || gen
->mGenerator
== 44)
422 /* Range generators accumulate by taking the intersection of
425 ALushort low
= maxu(i
->mAmount
&0x00ff, gen
->mAmount
&0x00ff);
426 ALushort high
= minu(i
->mAmount
&0xff00, gen
->mAmount
&0xff00);
427 i
->mAmount
= low
| high
;
430 i
->mAmount
+= gen
->mAmount
;
435 if(self
->gens_size
== self
->gens_max
)
440 newsize
= (self
->gens_max
? self
->gens_max
<<1 : 1);
441 if(newsize
> self
->gens_max
)
442 temp
= realloc(self
->gens
, newsize
* sizeof(self
->gens
[0]));
445 ERR("Failed to increase generator storage to %d elements (from %d)\n",
446 newsize
, self
->gens_max
);
451 self
->gens_max
= newsize
;
454 self
->gens
[self
->gens_size
] = *gen
;
455 if(gen
->mGenerator
< 60)
456 self
->gens
[self
->gens_size
].mAmount
+= DefaultGenValue
[gen
->mGenerator
];
460 static void GenModList_insertMod(GenModList
*self
, const Modulator
*mod
)
462 Modulator
*i
= self
->mods
;
463 Modulator
*end
= i
+ self
->mods_size
;
466 if(i
->mDstOp
== mod
->mDstOp
&& i
->mSrcOp
== mod
->mSrcOp
&&
467 i
->mAmtSrcOp
== mod
->mAmtSrcOp
&& i
->mTransOp
== mod
->mTransOp
)
469 i
->mAmount
= mod
->mAmount
;
474 if(self
->mods_size
== self
->mods_max
)
479 newsize
= (self
->mods_max
? self
->mods_max
<<1 : 1);
480 if(newsize
> self
->mods_max
)
481 temp
= realloc(self
->mods
, newsize
* sizeof(self
->mods
[0]));
484 ERR("Failed to increase modulator storage to %d elements (from %d)\n",
485 newsize
, self
->mods_max
);
490 self
->mods_max
= newsize
;
493 self
->mods
[self
->mods_size
] = *mod
;
496 static void GenModList_accumMod(GenModList
*self
, const Modulator
*mod
)
498 Modulator
*i
= self
->mods
;
499 Modulator
*end
= i
+ self
->mods_size
;
502 if(i
->mDstOp
== mod
->mDstOp
&& i
->mSrcOp
== mod
->mSrcOp
&&
503 i
->mAmtSrcOp
== mod
->mAmtSrcOp
&& i
->mTransOp
== mod
->mTransOp
)
505 i
->mAmount
+= mod
->mAmount
;
510 if(self
->mods_size
== self
->mods_max
)
515 newsize
= (self
->mods_max
? self
->mods_max
<<1 : 1);
516 if(newsize
> self
->mods_max
)
517 temp
= realloc(self
->mods
, newsize
* sizeof(self
->mods
[0]));
520 ERR("Failed to increase modulator storage to %d elements (from %d)\n",
521 newsize
, self
->mods_max
);
526 self
->mods_max
= newsize
;
529 self
->mods
[self
->mods_size
] = *mod
;
530 if(mod
->mSrcOp
== 0x0502 && mod
->mDstOp
== 48 && mod
->mAmtSrcOp
== 0 && mod
->mTransOp
== 0)
531 self
->mods
[self
->mods_size
].mAmount
+= 960;
532 else if(mod
->mSrcOp
== 0x0102 && mod
->mDstOp
== 8 && mod
->mAmtSrcOp
== 0 && mod
->mTransOp
== 0)
533 self
->mods
[self
->mods_size
].mAmount
+= -2400;
534 else if(mod
->mSrcOp
== 0x000D && mod
->mDstOp
== 6 && mod
->mAmtSrcOp
== 0 && mod
->mTransOp
== 0)
535 self
->mods
[self
->mods_size
].mAmount
+= 50;
536 else if(mod
->mSrcOp
== 0x0081 && mod
->mDstOp
== 6 && mod
->mAmtSrcOp
== 0 && mod
->mTransOp
== 0)
537 self
->mods
[self
->mods_size
].mAmount
+= 50;
538 else if(mod
->mSrcOp
== 0x0582 && mod
->mDstOp
== 48 && mod
->mAmtSrcOp
== 0 && mod
->mTransOp
== 0)
539 self
->mods
[self
->mods_size
].mAmount
+= 960;
540 else if(mod
->mSrcOp
== 0x028A && mod
->mDstOp
== 17 && mod
->mAmtSrcOp
== 0 && mod
->mTransOp
== 0)
541 self
->mods
[self
->mods_size
].mAmount
+= 1000;
542 else if(mod
->mSrcOp
== 0x058B && mod
->mDstOp
== 48 && mod
->mAmtSrcOp
== 0 && mod
->mTransOp
== 0)
543 self
->mods
[self
->mods_size
].mAmount
+= 960;
544 else if(mod
->mSrcOp
== 0x00DB && mod
->mDstOp
== 16 && mod
->mAmtSrcOp
== 0 && mod
->mTransOp
== 0)
545 self
->mods
[self
->mods_size
].mAmount
+= 200;
546 else if(mod
->mSrcOp
== 0x00DD && mod
->mDstOp
== 15 && mod
->mAmtSrcOp
== 0 && mod
->mTransOp
== 0)
547 self
->mods
[self
->mods_size
].mAmount
+= 200;
548 /*else if(mod->mSrcOp == 0x020E && mod->mDstOp == ?initialpitch? && mod->mAmtSrcOp == 0x0010 && mod->mTransOp == 0)
549 self->mods[self->mods_size].mAmount += 12700;*/
554 #define ERROR_GOTO(lbl_, ...) do { \
559 static ALboolean
ensureFontSanity(const Soundfont
*sfont
)
563 for(i
= 0;i
< sfont
->phdr_size
-1;i
++)
565 if(sfont
->phdr
[i
].mZoneIdx
>= sfont
->pbag_size
)
567 WARN("Preset %d has invalid zone index %d (max: %d)\n", i
,
568 sfont
->phdr
[i
].mZoneIdx
, sfont
->pbag_size
);
571 if(sfont
->phdr
[i
].mZoneIdx
> sfont
->phdr
[i
+1].mZoneIdx
)
573 WARN("Preset %d has invalid zone index (%d does not follow %d)\n", i
+1,
574 sfont
->phdr
[i
+1].mZoneIdx
, sfont
->phdr
[i
].mZoneIdx
);
578 if(sfont
->phdr
[i
].mZoneIdx
>= sfont
->pbag_size
)
580 WARN("Preset %d has invalid zone index %d (max: %d)\n", i
,
581 sfont
->phdr
[i
].mZoneIdx
, sfont
->pbag_size
);
585 for(i
= 0;i
< sfont
->pbag_size
-1;i
++)
587 if(sfont
->pbag
[i
].mGenIdx
>= sfont
->pgen_size
)
589 WARN("Preset zone %d has invalid generator index %d (max: %d)\n", i
,
590 sfont
->pbag
[i
].mGenIdx
, sfont
->pgen_size
);
593 if(sfont
->pbag
[i
].mGenIdx
> sfont
->pbag
[i
+1].mGenIdx
)
595 WARN("Preset zone %d has invalid generator index (%d does not follow %d)\n", i
+1,
596 sfont
->pbag
[i
+1].mGenIdx
, sfont
->pbag
[i
].mGenIdx
);
599 if(sfont
->pbag
[i
].mModIdx
>= sfont
->pmod_size
)
601 WARN("Preset zone %d has invalid modulator index %d (max: %d)\n", i
,
602 sfont
->pbag
[i
].mModIdx
, sfont
->pmod_size
);
605 if(sfont
->pbag
[i
].mModIdx
> sfont
->pbag
[i
+1].mModIdx
)
607 WARN("Preset zone %d has invalid modulator index (%d does not follow %d)\n", i
+1,
608 sfont
->pbag
[i
+1].mModIdx
, sfont
->pbag
[i
].mModIdx
);
612 if(sfont
->pbag
[i
].mGenIdx
>= sfont
->pgen_size
)
614 WARN("Preset zone %d has invalid generator index %d (max: %d)\n", i
,
615 sfont
->pbag
[i
].mGenIdx
, sfont
->pgen_size
);
618 if(sfont
->pbag
[i
].mModIdx
>= sfont
->pmod_size
)
620 WARN("Preset zone %d has invalid modulator index %d (max: %d)\n", i
,
621 sfont
->pbag
[i
].mModIdx
, sfont
->pmod_size
);
626 for(i
= 0;i
< sfont
->inst_size
-1;i
++)
628 if(sfont
->inst
[i
].mZoneIdx
>= sfont
->ibag_size
)
630 WARN("Instrument %d has invalid zone index %d (max: %d)\n", i
+1,
631 sfont
->inst
[i
].mZoneIdx
, sfont
->ibag_size
);
634 if(sfont
->inst
[i
].mZoneIdx
> sfont
->inst
[i
+1].mZoneIdx
)
636 WARN("Instrument %d has invalid zone index (%d does not follow %d)\n", i
+1,
637 sfont
->inst
[i
+1].mZoneIdx
, sfont
->inst
[i
].mZoneIdx
);
641 if(sfont
->inst
[i
].mZoneIdx
>= sfont
->ibag_size
)
643 WARN("Instrument %d has invalid zone index %d (max: %d)\n", i
+1,
644 sfont
->inst
[i
].mZoneIdx
, sfont
->ibag_size
);
648 for(i
= 0;i
< sfont
->ibag_size
-1;i
++)
650 if(sfont
->ibag
[i
].mGenIdx
>= sfont
->igen_size
)
652 WARN("Instrument zone %d has invalid generator index %d (max: %d)\n", i
,
653 sfont
->ibag
[i
].mGenIdx
, sfont
->igen_size
);
656 if(sfont
->ibag
[i
].mGenIdx
> sfont
->ibag
[i
+1].mGenIdx
)
658 WARN("Instrument zone %d has invalid generator index (%d does not follow %d)\n", i
+1,
659 sfont
->ibag
[i
+1].mGenIdx
, sfont
->ibag
[i
].mGenIdx
);
662 if(sfont
->ibag
[i
].mModIdx
>= sfont
->imod_size
)
664 WARN("Instrument zone %d has invalid modulator index %d (max: %d)\n", i
,
665 sfont
->ibag
[i
].mModIdx
, sfont
->imod_size
);
668 if(sfont
->ibag
[i
].mModIdx
> sfont
->ibag
[i
+1].mModIdx
)
670 WARN("Instrument zone %d has invalid modulator index (%d does not follow %d)\n", i
+1,
671 sfont
->ibag
[i
+1].mModIdx
, sfont
->ibag
[i
].mModIdx
);
675 if(sfont
->ibag
[i
].mGenIdx
>= sfont
->igen_size
)
677 WARN("Instrument zone %d has invalid generator index %d (max: %d)\n", i
,
678 sfont
->ibag
[i
].mGenIdx
, sfont
->igen_size
);
681 if(sfont
->ibag
[i
].mModIdx
>= sfont
->imod_size
)
683 WARN("Instrument zone %d has invalid modulator index %d (max: %d)\n", i
,
684 sfont
->ibag
[i
].mModIdx
, sfont
->imod_size
);
691 static ALboolean
checkZone(const GenModList
*zone
, const PresetHeader
*preset
, const InstrumentHeader
*inst
, const SampleHeader
*samp
)
695 for(i
= 0;i
< zone
->gens_size
;i
++)
697 if(zone
->gens
[i
].mGenerator
== 43 || zone
->gens
[i
].mGenerator
== 44)
699 int high
= zone
->gens
[i
].mAmount
>>8;
700 int low
= zone
->gens
[i
].mAmount
&0xff;
702 if(!(low
>= 0 && high
<= 127 && high
>= low
))
704 TRACE("Preset \"%s\", inst \"%s\", sample \"%s\": invalid %s range %d...%d\n",
705 preset
->mName
, inst
->mName
, samp
->mName
,
706 (zone
->gens
[i
].mGenerator
== 43) ? "key" :
707 (zone
->gens
[i
].mGenerator
== 44) ? "velocity" : "(unknown)",
717 static ALenum
getModSrcInput(int type
)
719 if(type
== 0) return AL_ONE_SOFT
;
720 if(type
== 2) return AL_NOTEON_VELOCITY_SOFT
;
721 if(type
== 3) return AL_NOTEON_KEY_SOFT
;
722 if(type
== 10) return AL_AFTERTOUCH_SOFT
;
723 if(type
== 13) return AL_CHANNELPRESSURE_SOFT
;
724 if(type
== 14) return AL_PITCHBEND_SOFT
;
725 if(type
== 16) return AL_PITCHBEND_SENSITIVITY_SOFT
;
729 if(type
> 0 && type
< 120 && !(type
== 6 || (type
>= 32 && type
<= 63) ||
730 (type
>= 98 && type
<= 101)))
734 ERR("Unhandled modulator source input: 0x%02x\n", type
);
738 static void fillZone(ALfontsound
*sound
, ALCcontext
*context
, const GenModList
*zone
)
740 static const ALenum Gen2Param
[60] = {
741 0, /* 0 - startAddrOffset */
742 0, /* 1 - endAddrOffset */
743 0, /* 2 - startloopAddrOffset */
744 0, /* 3 - endloopAddrOffset */
745 0, /* 4 - startAddrCoarseOffset */
746 AL_MOD_LFO_TO_PITCH_SOFT
, /* 5 - modLfoToPitch */
747 AL_VIBRATO_LFO_TO_PITCH_SOFT
, /* 6 - vibLfoToPitch */
748 AL_MOD_ENV_TO_PITCH_SOFT
, /* 7 - modEnvToPitch */
749 AL_FILTER_CUTOFF_SOFT
, /* 8 - initialFilterFc */
750 AL_FILTER_RESONANCE_SOFT
, /* 9 - initialFilterQ */
751 AL_MOD_LFO_TO_FILTER_CUTOFF_SOFT
, /* 10 - modLfoToFilterFc */
752 AL_MOD_ENV_TO_FILTER_CUTOFF_SOFT
, /* 11 - modEnvToFilterFc */
753 0, /* 12 - endAddrCoarseOffset */
754 AL_MOD_LFO_TO_VOLUME_SOFT
, /* 13 - modLfoToVolume */
756 AL_CHORUS_SEND_SOFT
, /* 15 - chorusEffectsSend */
757 AL_REVERB_SEND_SOFT
, /* 16 - reverbEffectsSend */
758 AL_PAN_SOFT
, /* 17 - pan */
762 AL_MOD_LFO_DELAY_SOFT
, /* 21 - delayModLFO */
763 AL_MOD_LFO_FREQUENCY_SOFT
, /* 22 - freqModLFO */
764 AL_VIBRATO_LFO_DELAY_SOFT
, /* 23 - delayVibLFO */
765 AL_VIBRATO_LFO_FREQUENCY_SOFT
, /* 24 - freqVibLFO */
766 AL_MOD_ENV_DELAYTIME_SOFT
, /* 25 - delayModEnv */
767 AL_MOD_ENV_ATTACKTIME_SOFT
, /* 26 - attackModEnv */
768 AL_MOD_ENV_HOLDTIME_SOFT
, /* 27 - holdModEnv */
769 AL_MOD_ENV_DECAYTIME_SOFT
, /* 28 - decayModEnv */
770 AL_MOD_ENV_SUSTAINVOLUME_SOFT
, /* 29 - sustainModEnv */
771 AL_MOD_ENV_RELEASETIME_SOFT
, /* 30 - releaseModEnv */
772 AL_MOD_ENV_KEY_TO_HOLDTIME_SOFT
, /* 31 - keynumToModEnvHold */
773 AL_MOD_ENV_KEY_TO_DECAYTIME_SOFT
, /* 32 - keynumToModEnvDecay */
774 AL_VOLUME_ENV_DELAYTIME_SOFT
, /* 33 - delayVolEnv */
775 AL_VOLUME_ENV_ATTACKTIME_SOFT
, /* 34 - attackVolEnv */
776 AL_VOLUME_ENV_HOLDTIME_SOFT
, /* 35 - holdVolEnv */
777 AL_VOLUME_ENV_DECAYTIME_SOFT
, /* 36 - decayVolEnv */
778 AL_VOLUME_ENV_SUSTAINVOLUME_SOFT
, /* 37 - sustainVolEnv */
779 AL_VOLUME_ENV_RELEASETIME_SOFT
, /* 38 - releaseVolEnv */
780 AL_VOLUME_ENV_KEY_TO_HOLDTIME_SOFT
, /* 39 - keynumToVolEnvHold */
781 AL_VOLUME_ENV_KEY_TO_DECAYTIME_SOFT
, /* 40 - keynumToVolEnvDecay */
784 AL_KEY_RANGE_SOFT
, /* 43 - keyRange */
785 AL_VELOCITY_RANGE_SOFT
, /* 44 - velRange */
786 0, /* 45 - startloopAddrCoarseOffset */
788 0, /* 47 - velocity */
789 AL_ATTENUATION_SOFT
, /* 48 - initialAttenuation */
791 0, /* 50 - endloopAddrCoarseOffset */
792 AL_TUNING_COARSE_SOFT
, /* 51 - corseTune */
793 AL_TUNING_FINE_SOFT
, /* 52 - fineTune */
795 AL_LOOP_MODE_SOFT
, /* 54 - sampleModes */
797 AL_TUNING_SCALE_SOFT
, /* 56 - scaleTuning */
798 AL_EXCLUSIVE_CLASS_SOFT
, /* 57 - exclusiveClass */
799 AL_BASE_KEY_SOFT
, /* 58 - overridingRootKey */
802 const Generator
*gen
, *gen_end
;
807 for(i
= 0;i
< zone
->mods_size
;i
++)
809 ALenum src0in
= getModSrcInput(zone
->mods
[i
].mSrcOp
&0xFF);
810 ALenum src0form
= (zone
->mods
[i
].mSrcOp
&0xFC00);
811 ALenum src1in
= getModSrcInput(zone
->mods
[i
].mAmtSrcOp
&0xFF);
812 ALenum src1form
= (zone
->mods
[i
].mAmtSrcOp
&0xFC00);
813 ALenum trans
= zone
->mods
[i
].mTransOp
;
814 ALenum dst
= (zone
->mods
[i
].mDstOp
< 60) ? Gen2Param
[zone
->mods
[i
].mDstOp
] : 0;
816 ERR("Unhandled modulator destination: %d\n", zone
->mods
[i
].mDstOp
);
817 if((src0form
&0xF000))
818 ERR("Unhandled modulator source form: 0x%04x\n", src0form
);
819 if((src1form
&0xF000))
820 ERR("Unhandled modulator source form: 0x%04x\n", src1form
);
821 if(!(trans
== 0 || trans
== 2))
822 ERR("Unhandled modulator transform: %d\n", trans
);
823 if(src0in
&& !(src0form
&0xF000) && src1in
&& !(src1form
&0xF000) &&
824 (trans
== 0 || trans
== 2) && dst
)
826 ALfontsound_setModStagei(sound
, context
, i
, AL_SOURCE0_INPUT_SOFT
, src0in
);
827 ALfontsound_setModStagei(sound
, context
, i
, AL_SOURCE0_TYPE_SOFT
, (zone
->mods
[i
].mSrcOp
&0x300));
828 ALfontsound_setModStagei(sound
, context
, i
, AL_SOURCE0_FORM_SOFT
, src0form
);
829 ALfontsound_setModStagei(sound
, context
, i
, AL_SOURCE1_INPUT_SOFT
, src1in
);
830 ALfontsound_setModStagei(sound
, context
, i
, AL_SOURCE1_TYPE_SOFT
, (zone
->mods
[i
].mAmtSrcOp
&0x300));
831 ALfontsound_setModStagei(sound
, context
, i
, AL_SOURCE1_FORM_SOFT
, src1form
);
832 ALfontsound_setModStagei(sound
, context
, i
, AL_AMOUNT_SOFT
, zone
->mods
[i
].mAmount
);
833 ALfontsound_setModStagei(sound
, context
, i
, AL_TRANSFORM_OP_SOFT
, trans
);
834 ALfontsound_setModStagei(sound
, context
, i
, AL_DESTINATION_SOFT
, dst
);
840 gen_end
= gen
+ zone
->gens_size
;
841 for(;gen
!= gen_end
;gen
++)
843 ALint value
= (ALshort
)gen
->mAmount
;
844 if(gen
->mGenerator
== 0)
845 sound
->Start
+= value
;
846 else if(gen
->mGenerator
== 1)
848 else if(gen
->mGenerator
== 2)
849 sound
->LoopStart
+= value
;
850 else if(gen
->mGenerator
== 3)
851 sound
->LoopEnd
+= value
;
852 else if(gen
->mGenerator
== 4)
853 sound
->Start
+= value
<<15;
854 else if(gen
->mGenerator
== 12)
855 sound
->End
+= value
<<15;
856 else if(gen
->mGenerator
== 45)
857 sound
->LoopStart
+= value
<<15;
858 else if(gen
->mGenerator
== 50)
859 sound
->LoopEnd
+= value
<<15;
860 else if(gen
->mGenerator
== 43)
862 sound
->MinKey
= mini((value
&0xff), 127);
863 sound
->MaxKey
= mini(((value
>>8)&0xff), 127);
865 else if(gen
->mGenerator
== 44)
867 sound
->MinVelocity
= mini((value
&0xff), 127);
868 sound
->MaxVelocity
= mini(((value
>>8)&0xff), 127);
873 if(gen
->mGenerator
< 60)
874 param
= Gen2Param
[gen
->mGenerator
];
877 if(param
== AL_BASE_KEY_SOFT
&& value
== -1)
879 if(param
== AL_FILTER_RESONANCE_SOFT
|| param
== AL_ATTENUATION_SOFT
)
880 value
= maxi(0, value
);
881 else if(param
== AL_CHORUS_SEND_SOFT
|| param
== AL_REVERB_SEND_SOFT
)
882 value
= clampi(value
, 0, 1000);
883 else if(param
== AL_LOOP_MODE_SOFT
)
885 if(!(value
== 0 || value
== 1 || value
== 3))
888 ALfontsound_setPropi(sound
, context
, param
, value
);
890 else if(gen
->mGenerator
< 256)
892 static ALboolean warned
[256];
893 if(!warned
[gen
->mGenerator
])
895 warned
[gen
->mGenerator
] = AL_TRUE
;
896 ERR("Unhandled generator %d\n", gen
->mGenerator
);
903 static void processInstrument(ALfontsound
***sounds
, ALsizei
*sounds_size
, ALCcontext
*context
, InstrumentHeader
*inst
, const PresetHeader
*preset
, const Soundfont
*sfont
, const GenModList
*pzone
)
905 const Generator
*gen
, *gen_end
;
906 const Modulator
*mod
, *mod_end
;
907 const Zone
*zone
, *zone_end
;
911 if((inst
+1)->mZoneIdx
== inst
->mZoneIdx
)
912 ERR("Instrument with no zones!");
914 GenModList_Construct(&gzone
);
915 zone
= sfont
->ibag
+ inst
->mZoneIdx
;
916 zone_end
= sfont
->ibag
+ (inst
+1)->mZoneIdx
;
917 if(zone_end
-zone
> 1)
919 gen
= sfont
->igen
+ zone
->mGenIdx
;
920 gen_end
= sfont
->igen
+ (zone
+1)->mGenIdx
;
922 // If no generators, or last generator is not a sample, this is a global zone
923 for(;gen
!= gen_end
;gen
++)
925 if(gen
->mGenerator
== 53)
931 gen
= sfont
->igen
+ zone
->mGenIdx
;
932 gen_end
= sfont
->igen
+ (zone
+1)->mGenIdx
;
933 for(;gen
!= gen_end
;gen
++)
934 GenModList_insertGen(&gzone
, gen
, AL_FALSE
);
936 mod
= sfont
->imod
+ zone
->mModIdx
;
937 mod_end
= sfont
->imod
+ (zone
+1)->mModIdx
;
938 for(;mod
!= mod_end
;mod
++)
939 GenModList_insertMod(&gzone
, mod
);
945 temp
= realloc(*sounds
, (zone_end
-zone
+ *sounds_size
)*sizeof((*sounds
)[0]));
948 ERR("Failed reallocating fontsound storage to %ld elements (from %d)\n",
949 (zone_end
-zone
+ *sounds_size
), *sounds_size
);
953 for(;zone
!= zone_end
;zone
++)
955 GenModList lzone
= GenModList_clone(&gzone
);
956 mod
= sfont
->imod
+ zone
->mModIdx
;
957 mod_end
= sfont
->imod
+ (zone
+1)->mModIdx
;
958 for(;mod
!= mod_end
;mod
++)
959 GenModList_insertMod(&lzone
, mod
);
961 gen
= sfont
->igen
+ zone
->mGenIdx
;
962 gen_end
= sfont
->igen
+ (zone
+1)->mGenIdx
;
963 for(;gen
!= gen_end
;gen
++)
965 if(gen
->mGenerator
== 53)
967 const SampleHeader
*samp
;
969 if(gen
->mAmount
>= sfont
->shdr_size
-1)
971 ERR("Generator %ld has invalid sample ID generator (%d of %d)\n",
972 (long)(gen
-sfont
->igen
), gen
->mAmount
, sfont
->shdr_size
-1);
975 samp
= &sfont
->shdr
[gen
->mAmount
];
978 gen_end
= gen
+ pzone
->gens_size
;
979 for(;gen
!= gen_end
;gen
++)
980 GenModList_accumGen(&lzone
, gen
);
983 mod_end
= mod
+ pzone
->mods_size
;
984 for(;mod
!= mod_end
;mod
++)
985 GenModList_accumMod(&lzone
, mod
);
987 if(!checkZone(&lzone
, preset
, inst
, samp
))
990 (*sounds
)[*sounds_size
] = NewFontsound(context
);
991 (*sounds
)[*sounds_size
]->Start
= samp
->mStart
;
992 (*sounds
)[*sounds_size
]->End
= samp
->mEnd
;
993 (*sounds
)[*sounds_size
]->LoopStart
= samp
->mStartloop
;
994 (*sounds
)[*sounds_size
]->LoopEnd
= samp
->mEndloop
;
995 (*sounds
)[*sounds_size
]->SampleRate
= samp
->mSampleRate
;
996 (*sounds
)[*sounds_size
]->PitchKey
= samp
->mOriginalKey
;
997 (*sounds
)[*sounds_size
]->PitchCorrection
= samp
->mCorrection
;
998 (*sounds
)[*sounds_size
]->LoopMode
= (samp
->mSampleType
&0x7ffff);
999 fillZone((*sounds
)[*sounds_size
], context
, &lzone
);
1004 GenModList_insertGen(&lzone
, gen
, AL_FALSE
);
1007 GenModList_Destruct(&lzone
);
1010 GenModList_Destruct(&gzone
);
1013 ALboolean
loadSf2(Reader
*stream
, ALsoundfont
*soundfont
, ALCcontext
*context
)
1015 ALsfpreset
**presets
= NULL
;
1016 ALsizei presets_size
= 0;
1024 Soundfont_Construct(&sfont
);
1026 RiffHdr_read(&riff
, stream
);
1027 if(riff
.mCode
!= FOURCC('R','I','F','F'))
1028 ERROR_GOTO(error
, "Invalid Format, expected RIFF got '%c%c%c%c'\n", FOURCCARGS(riff
.mCode
));
1029 if((ltype
=read_le32(stream
)) != FOURCC('s','f','b','k'))
1030 ERROR_GOTO(error
, "Invalid Format, expected sfbk got '%c%c%c%c'\n", FOURCCARGS(ltype
));
1032 if(READERR(stream
) != 0)
1033 ERROR_GOTO(error
, "Error reading file header\n");
1035 RiffHdr_read(&list
, stream
);
1036 if(list
.mCode
!= FOURCC('L','I','S','T'))
1037 ERROR_GOTO(error
, "Invalid Format, expected LIST (INFO) got '%c%c%c%c'\n", FOURCCARGS(list
.mCode
));
1038 if((ltype
=read_le32(stream
)) != FOURCC('I','N','F','O'))
1039 ERROR_GOTO(error
, "Invalid Format, expected INFO got '%c%c%c%c'\n", FOURCCARGS(ltype
));
1041 while(list
.mSize
> 0 && !READERR(stream
))
1045 RiffHdr_read(&info
, stream
);
1047 if(info
.mCode
== FOURCC('i','f','i','l'))
1050 ERR("Invalid ifil chunk size: %d\n", info
.mSize
);
1053 ALushort major
= read_le16(stream
);
1054 ALushort minor
= read_le16(stream
);
1059 version
= (major
<<16) | minor
;
1062 list
.mSize
-= info
.mSize
;
1063 skip(stream
, info
.mSize
);
1066 if(READERR(stream
) != 0)
1067 ERROR_GOTO(error
, "Error reading INFO chunk\n");
1068 if(version
>>16 != 2)
1069 ERROR_GOTO(error
, "Unsupported format version: %d.%02d\n", version
>>16, version
&0xffff);
1070 TRACE("Loading SF2 format version: %d.%02d\n", version
>>16, version
&0xffff);
1072 RiffHdr_read(&list
, stream
);
1073 if(list
.mCode
!= FOURCC('L','I','S','T'))
1074 ERROR_GOTO(error
, "Invalid Format, expected LIST (sdta) got '%c%c%c%c'\n", FOURCCARGS(list
.mCode
));
1075 if((ltype
=read_le32(stream
)) != FOURCC('s','d','t','a'))
1076 ERROR_GOTO(error
, "Invalid Format, expected sdta got '%c%c%c%c'\n", FOURCCARGS(ltype
));
1082 RiffHdr_read(&smpl
, stream
);
1083 if(smpl
.mCode
!= FOURCC('s','m','p','l'))
1084 ERROR_GOTO(error
, "Invalid Format, expected smpl got '%c%c%c%c'\n", FOURCCARGS(smpl
.mCode
));
1087 if(smpl
.mSize
> list
.mSize
)
1088 ERROR_GOTO(error
, "Invalid Format, sample chunk size mismatch\n");
1090 if(!(ptr
=realloc(soundfont
->Samples
, smpl
.mSize
)))
1091 SET_ERROR_AND_GOTO(context
, AL_OUT_OF_MEMORY
, error
);
1092 soundfont
->Samples
= (ALshort
*)ptr
;
1093 soundfont
->NumSamples
= smpl
.mSize
/2;
1095 if(IS_LITTLE_ENDIAN
)
1096 READ(stream
, ptr
, smpl
.mSize
);
1099 while(smpl
.mSize
> 0)
1102 ALuint todo
= minu(smpl
.mSize
, sizeof(buf
));
1105 READ(stream
, buf
, todo
);
1106 for(i
= 0;i
< todo
;i
++)
1110 list
.mSize
-= smpl
.mSize
;
1112 skip(stream
, list
.mSize
);
1115 if(READERR(stream
) != 0)
1116 ERROR_GOTO(error
, "Error reading sdta chunk\n");
1118 RiffHdr_read(&list
, stream
);
1119 if(list
.mCode
!= FOURCC('L','I','S','T'))
1120 ERROR_GOTO(error
, "Invalid Format, expected LIST (pdta) got '%c%c%c%c'\n", FOURCCARGS(list
.mCode
));
1121 if((ltype
=read_le32(stream
)) != FOURCC('p','d','t','a'))
1122 ERROR_GOTO(error
, "Invalid Format, expected pdta got '%c%c%c%c'\n", FOURCCARGS(ltype
));
1125 RiffHdr_read(&list
, stream
);
1126 if(list
.mCode
!= FOURCC('p','h','d','r'))
1127 ERROR_GOTO(error
, "Invalid Format, expected phdr got '%c%c%c%c'\n", FOURCCARGS(list
.mCode
));
1128 if((list
.mSize
%38) != 0)
1129 ERROR_GOTO(error
, "Invalid Format, bad phdr size\n");
1130 sfont
.phdr_size
= list
.mSize
/38;
1131 sfont
.phdr
= calloc(sfont
.phdr_size
, sizeof(sfont
.phdr
[0]));
1132 for(i
= 0;i
< sfont
.phdr_size
;i
++)
1133 PresetHeader_read(&sfont
.phdr
[i
], stream
);
1135 RiffHdr_read(&list
, stream
);
1136 if(list
.mCode
!= FOURCC('p','b','a','g'))
1137 ERROR_GOTO(error
, "Invalid Format, expected pbag got '%c%c%c%c'\n", FOURCCARGS(list
.mCode
));
1138 if((list
.mSize
%4) != 0)
1139 ERROR_GOTO(error
, "Invalid Format, bad pbag size\n");
1140 sfont
.pbag_size
= list
.mSize
/4;
1141 sfont
.pbag
= calloc(sfont
.pbag_size
, sizeof(sfont
.pbag
[0]));
1142 for(i
= 0;i
< sfont
.pbag_size
;i
++)
1143 Zone_read(&sfont
.pbag
[i
], stream
);
1145 RiffHdr_read(&list
, stream
);
1146 if(list
.mCode
!= FOURCC('p','m','o','d'))
1147 ERROR_GOTO(error
, "Invalid Format, expected pmod got '%c%c%c%c'\n", FOURCCARGS(list
.mCode
));
1148 if((list
.mSize
%10) != 0)
1149 ERROR_GOTO(error
, "Invalid Format, bad pmod size\n");
1150 sfont
.pmod_size
= list
.mSize
/10;
1151 sfont
.pmod
= calloc(sfont
.pmod_size
, sizeof(sfont
.pmod
[0]));
1152 for(i
= 0;i
< sfont
.pmod_size
;i
++)
1153 Modulator_read(&sfont
.pmod
[i
], stream
);
1155 RiffHdr_read(&list
, stream
);
1156 if(list
.mCode
!= FOURCC('p','g','e','n'))
1157 ERROR_GOTO(error
, "Invalid Format, expected pgen got '%c%c%c%c'\n", FOURCCARGS(list
.mCode
));
1158 if((list
.mSize
%4) != 0)
1159 ERROR_GOTO(error
, "Invalid Format, bad pgen size\n");
1160 sfont
.pgen_size
= list
.mSize
/4;
1161 sfont
.pgen
= calloc(sfont
.pgen_size
, sizeof(sfont
.pgen
[0]));
1162 for(i
= 0;i
< sfont
.pgen_size
;i
++)
1163 Generator_read(&sfont
.pgen
[i
], stream
);
1166 RiffHdr_read(&list
, stream
);
1167 if(list
.mCode
!= FOURCC('i','n','s','t'))
1168 ERROR_GOTO(error
, "Invalid Format, expected inst got '%c%c%c%c'\n", FOURCCARGS(list
.mCode
));
1169 if((list
.mSize
%22) != 0)
1170 ERROR_GOTO(error
, "Invalid Format, bad inst size\n");
1171 sfont
.inst_size
= list
.mSize
/22;
1172 sfont
.inst
= calloc(sfont
.inst_size
, sizeof(sfont
.inst
[0]));
1173 for(i
= 0;i
< sfont
.inst_size
;i
++)
1174 InstrumentHeader_read(&sfont
.inst
[i
], stream
);
1176 RiffHdr_read(&list
, stream
);
1177 if(list
.mCode
!= FOURCC('i','b','a','g'))
1178 ERROR_GOTO(error
, "Invalid Format, expected ibag got '%c%c%c%c'\n", FOURCCARGS(list
.mCode
));
1179 if((list
.mSize
%4) != 0)
1180 ERROR_GOTO(error
, "Invalid Format, bad ibag size\n");
1181 sfont
.ibag_size
= list
.mSize
/4;
1182 sfont
.ibag
= calloc(sfont
.ibag_size
, sizeof(sfont
.ibag
[0]));
1183 for(i
= 0;i
< sfont
.ibag_size
;i
++)
1184 Zone_read(&sfont
.ibag
[i
], stream
);
1186 RiffHdr_read(&list
, stream
);
1187 if(list
.mCode
!= FOURCC('i','m','o','d'))
1188 ERROR_GOTO(error
, "Invalid Format, expected imod got '%c%c%c%c'\n", FOURCCARGS(list
.mCode
));
1189 if((list
.mSize
%10) != 0)
1190 ERROR_GOTO(error
, "Invalid Format, bad imod size\n");
1191 sfont
.imod_size
= list
.mSize
/10;
1192 sfont
.imod
= calloc(sfont
.imod_size
, sizeof(sfont
.imod
[0]));
1193 for(i
= 0;i
< sfont
.imod_size
;i
++)
1194 Modulator_read(&sfont
.imod
[i
], stream
);
1196 RiffHdr_read(&list
, stream
);
1197 if(list
.mCode
!= FOURCC('i','g','e','n'))
1198 ERROR_GOTO(error
, "Invalid Format, expected igen got '%c%c%c%c'\n", FOURCCARGS(list
.mCode
));
1199 if((list
.mSize
%4) != 0)
1200 ERROR_GOTO(error
, "Invalid Format, bad igen size\n");
1201 sfont
.igen_size
= list
.mSize
/4;
1202 sfont
.igen
= calloc(sfont
.igen_size
, sizeof(sfont
.igen
[0]));
1203 for(i
= 0;i
< sfont
.igen_size
;i
++)
1204 Generator_read(&sfont
.igen
[i
], stream
);
1207 RiffHdr_read(&list
, stream
);
1208 if(list
.mCode
!= FOURCC('s','h','d','r'))
1209 ERROR_GOTO(error
, "Invalid Format, expected shdr got '%c%c%c%c'\n", FOURCCARGS(list
.mCode
));
1210 if((list
.mSize
%46) != 0)
1211 ERROR_GOTO(error
, "Invalid Format, bad shdr size\n");
1212 sfont
.shdr_size
= list
.mSize
/46;
1213 sfont
.shdr
= calloc(sfont
.shdr_size
, sizeof(sfont
.shdr
[0]));
1214 for(i
= 0;i
< sfont
.shdr_size
;i
++)
1215 SampleHeader_read(&sfont
.shdr
[i
], stream
);
1217 if(READERR(stream
) != 0)
1218 ERROR_GOTO(error
, "Error reading pdta chunk\n");
1220 if(!ensureFontSanity(&sfont
))
1223 presets
= calloc(1, (sfont
.phdr_size
-1)*sizeof(presets
[0]));
1225 ERROR_GOTO(error
, "Error allocating presets\n");
1227 for(i
= 0;i
< sfont
.phdr_size
-1;i
++)
1229 const Generator
*gen
, *gen_end
;
1230 const Modulator
*mod
, *mod_end
;
1231 const Zone
*zone
, *zone_end
;
1232 ALfontsound
**sounds
= NULL
;
1233 ALsizei sounds_size
= 0;
1236 if(sfont
.phdr
[i
+1].mZoneIdx
== sfont
.phdr
[i
].mZoneIdx
)
1239 GenModList_Construct(&gzone
);
1240 zone
= sfont
.pbag
+ sfont
.phdr
[i
].mZoneIdx
;
1241 zone_end
= sfont
.pbag
+ sfont
.phdr
[i
+1].mZoneIdx
;
1242 if(zone_end
-zone
> 1)
1244 gen
= sfont
.pgen
+ zone
->mGenIdx
;
1245 gen_end
= sfont
.pgen
+ (zone
+1)->mGenIdx
;
1247 // If no generators, or last generator is not an instrument, this is a global zone
1248 for(;gen
!= gen_end
;gen
++)
1250 if(gen
->mGenerator
== 41)
1256 gen
= sfont
.pgen
+ zone
->mGenIdx
;
1257 gen_end
= sfont
.pgen
+ (zone
+1)->mGenIdx
;
1258 for(;gen
!= gen_end
;gen
++)
1259 GenModList_insertGen(&gzone
, gen
, AL_TRUE
);
1261 mod
= sfont
.pmod
+ zone
->mModIdx
;
1262 mod_end
= sfont
.pmod
+ (zone
+1)->mModIdx
;
1263 for(;mod
!= mod_end
;mod
++)
1264 GenModList_insertMod(&gzone
, mod
);
1270 for(;zone
!= zone_end
;zone
++)
1272 GenModList lzone
= GenModList_clone(&gzone
);
1274 mod
= sfont
.pmod
+ zone
->mModIdx
;
1275 mod_end
= sfont
.pmod
+ (zone
+1)->mModIdx
;
1276 for(;mod
!= mod_end
;mod
++)
1277 GenModList_insertMod(&lzone
, mod
);
1279 gen
= sfont
.pgen
+ zone
->mGenIdx
;
1280 gen_end
= sfont
.pgen
+ (zone
+1)->mGenIdx
;
1281 for(;gen
!= gen_end
;gen
++)
1283 if(gen
->mGenerator
== 41)
1285 if(gen
->mAmount
>= sfont
.inst_size
-1)
1286 ERR("Generator %ld has invalid instrument ID generator (%d of %d)\n",
1287 (long)(gen
-sfont
.pgen
), gen
->mAmount
, sfont
.inst_size
-1);
1289 processInstrument(&sounds
, &sounds_size
, context
,
1290 &sfont
.inst
[gen
->mAmount
], &sfont
.phdr
[i
], &sfont
, &lzone
);
1293 GenModList_insertGen(&lzone
, gen
, AL_TRUE
);
1295 GenModList_Destruct(&lzone
);
1302 presets
[presets_size
] = NewPreset(context
);
1303 presets
[presets_size
]->Preset
= sfont
.phdr
[i
].mPreset
;
1304 presets
[presets_size
]->Bank
= sfont
.phdr
[i
].mBank
;
1306 for(j
= 0;j
< sounds_size
;j
++)
1307 IncrementRef(&sounds
[j
]->ref
);
1308 sounds
= ExchangePtr((XchgPtr
*)&presets
[presets_size
]->Sounds
, sounds
);
1309 ExchangeInt(&presets
[presets_size
]->NumSounds
, sounds_size
);
1314 GenModList_Destruct(&gzone
);
1317 for(i
= 0;i
< presets_size
;i
++)
1318 IncrementRef(&presets
[i
]->ref
);
1319 presets
= ExchangePtr((XchgPtr
*)&soundfont
->Presets
, presets
);
1320 ExchangeInt(&soundfont
->NumPresets
, presets_size
);
1324 Soundfont_Destruct(&sfont
);
1331 ALCdevice
*device
= context
->Device
;
1332 for(i
= 0;i
< presets_size
;i
++)
1333 DeletePreset(presets
[i
], device
);
1337 Soundfont_Destruct(&sfont
);