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
{
232 InstrumentHeader
*inst
;
246 static void Soundfont_Construct(Soundfont
*self
)
275 static void Soundfont_Destruct(Soundfont
*self
)
314 #define FOURCC(a,b,c,d) (((d)<<24) | ((c)<<16) | ((b)<<8) | (a))
315 #define FOURCCARGS(x) (char)((x)&0xff), (char)(((x)>>8)&0xff), (char)(((x)>>16)&0xff), (char)(((x)>>24)&0xff)
316 typedef struct RiffHdr
{
320 static void RiffHdr_read(RiffHdr
*self
, Reader
*stream
)
322 self
->mCode
= read_le32(stream
);
323 self
->mSize
= read_le32(stream
);
327 DECL_VECTOR(Generator
)
328 DECL_VECTOR(Modulator
)
330 typedef struct GenModList
{
331 vector_Generator gens
;
332 vector_Modulator mods
;
335 static void GenModList_Construct(GenModList
*self
)
337 VECTOR_INIT(self
->gens
);
338 VECTOR_INIT(self
->mods
);
341 static void GenModList_Destruct(GenModList
*self
)
343 VECTOR_DEINIT(self
->mods
);
344 VECTOR_DEINIT(self
->gens
);
347 static GenModList
GenModList_clone(const GenModList
*self
)
351 GenModList_Construct(&ret
);
352 VECTOR_RESERVE(ret
.gens
, VECTOR_MAX(self
->gens
));
353 memcpy(ret
.gens
, self
->gens
, sizeof(ret
.gens
) +
354 VECTOR_MAX(ret
.gens
) * sizeof(ret
.gens
->Data
[0]));
355 VECTOR_RESERVE(ret
.mods
, VECTOR_MAX(self
->mods
));
356 memcpy(ret
.mods
, self
->mods
, sizeof(ret
.mods
) +
357 VECTOR_MAX(ret
.mods
) * sizeof(ret
.mods
->Data
[0]));
362 static void GenModList_insertGen(GenModList
*self
, const Generator
*gen
, ALboolean ispreset
)
364 Generator
*i
= VECTOR_ITER_BEGIN(self
->gens
);
365 Generator
*end
= VECTOR_ITER_END(self
->gens
);
368 if(i
->mGenerator
== gen
->mGenerator
)
370 i
->mAmount
= gen
->mAmount
;
376 (gen
->mGenerator
== 0 || gen
->mGenerator
== 1 || gen
->mGenerator
== 2 ||
377 gen
->mGenerator
== 3 || gen
->mGenerator
== 4 || gen
->mGenerator
== 12 ||
378 gen
->mGenerator
== 45 || gen
->mGenerator
== 46 || gen
->mGenerator
== 47 ||
379 gen
->mGenerator
== 50 || gen
->mGenerator
== 54 || gen
->mGenerator
== 57 ||
380 gen
->mGenerator
== 58))
383 if(VECTOR_RESERVE(self
->gens
, NextPowerOf2(VECTOR_SIZE(self
->gens
)+1)) == AL_FALSE
)
385 ERR("Failed to increase generator storage to %d elements (from %d)\n",
386 NextPowerOf2(VECTOR_SIZE(self
->gens
)+1), VECTOR_MAX(self
->gens
));
390 VECTOR_PUSH_BACK(self
->gens
, *gen
);
392 static void GenModList_accumGen(GenModList
*self
, const Generator
*gen
)
394 Generator
*i
= VECTOR_ITER_BEGIN(self
->gens
);
395 Generator
*end
= VECTOR_ITER_END(self
->gens
);
398 if(i
->mGenerator
== gen
->mGenerator
)
400 if(gen
->mGenerator
== 43 || gen
->mGenerator
== 44)
402 /* Range generators accumulate by taking the intersection of
405 ALushort low
= maxu(i
->mAmount
&0x00ff, gen
->mAmount
&0x00ff);
406 ALushort high
= minu(i
->mAmount
&0xff00, gen
->mAmount
&0xff00);
407 i
->mAmount
= low
| high
;
410 i
->mAmount
+= gen
->mAmount
;
415 if(VECTOR_RESERVE(self
->gens
, NextPowerOf2(VECTOR_SIZE(self
->gens
)+1)) == AL_FALSE
)
417 ERR("Failed to increase generator storage to %d elements (from %d)\n",
418 NextPowerOf2(VECTOR_SIZE(self
->gens
)+1), VECTOR_MAX(self
->gens
));
422 VECTOR_PUSH_BACK(self
->gens
, *gen
);
423 if(gen
->mGenerator
< 60)
424 VECTOR_BACK(self
->gens
).mAmount
+= DefaultGenValue
[gen
->mGenerator
];
427 static void GenModList_insertMod(GenModList
*self
, const Modulator
*mod
)
429 Modulator
*i
= VECTOR_ITER_BEGIN(self
->mods
);
430 Modulator
*end
= VECTOR_ITER_END(self
->mods
);
433 if(i
->mDstOp
== mod
->mDstOp
&& i
->mSrcOp
== mod
->mSrcOp
&&
434 i
->mAmtSrcOp
== mod
->mAmtSrcOp
&& i
->mTransOp
== mod
->mTransOp
)
436 i
->mAmount
= mod
->mAmount
;
441 if(VECTOR_RESERVE(self
->mods
, NextPowerOf2(VECTOR_SIZE(self
->mods
)+1)) == AL_FALSE
)
443 ERR("Failed to increase modulator storage to %d elements (from %d)\n",
444 NextPowerOf2(VECTOR_SIZE(self
->mods
)+1), VECTOR_MAX(self
->mods
));
448 VECTOR_PUSH_BACK(self
->mods
, *mod
);
450 static void GenModList_accumMod(GenModList
*self
, const Modulator
*mod
)
452 Modulator
*i
= VECTOR_ITER_BEGIN(self
->mods
);
453 Modulator
*end
= VECTOR_ITER_END(self
->mods
);
456 if(i
->mDstOp
== mod
->mDstOp
&& i
->mSrcOp
== mod
->mSrcOp
&&
457 i
->mAmtSrcOp
== mod
->mAmtSrcOp
&& i
->mTransOp
== mod
->mTransOp
)
459 i
->mAmount
+= mod
->mAmount
;
464 if(VECTOR_RESERVE(self
->mods
, NextPowerOf2(VECTOR_SIZE(self
->mods
)+1)) == AL_FALSE
)
466 ERR("Failed to increase modulator storage to %d elements (from %d)\n",
467 NextPowerOf2(VECTOR_SIZE(self
->mods
)+1), VECTOR_MAX(self
->mods
));
471 VECTOR_PUSH_BACK(self
->mods
, *mod
);
472 if(mod
->mSrcOp
== 0x0502 && mod
->mDstOp
== 48 && mod
->mAmtSrcOp
== 0 && mod
->mTransOp
== 0)
473 VECTOR_BACK(self
->mods
).mAmount
+= 960;
474 else if(mod
->mSrcOp
== 0x0102 && mod
->mDstOp
== 8 && mod
->mAmtSrcOp
== 0 && mod
->mTransOp
== 0)
475 VECTOR_BACK(self
->mods
).mAmount
+= -2400;
476 else if(mod
->mSrcOp
== 0x000D && mod
->mDstOp
== 6 && mod
->mAmtSrcOp
== 0 && mod
->mTransOp
== 0)
477 VECTOR_BACK(self
->mods
).mAmount
+= 50;
478 else if(mod
->mSrcOp
== 0x0081 && mod
->mDstOp
== 6 && mod
->mAmtSrcOp
== 0 && mod
->mTransOp
== 0)
479 VECTOR_BACK(self
->mods
).mAmount
+= 50;
480 else if(mod
->mSrcOp
== 0x0582 && mod
->mDstOp
== 48 && mod
->mAmtSrcOp
== 0 && mod
->mTransOp
== 0)
481 VECTOR_BACK(self
->mods
).mAmount
+= 960;
482 else if(mod
->mSrcOp
== 0x028A && mod
->mDstOp
== 17 && mod
->mAmtSrcOp
== 0 && mod
->mTransOp
== 0)
483 VECTOR_BACK(self
->mods
).mAmount
+= 1000;
484 else if(mod
->mSrcOp
== 0x058B && mod
->mDstOp
== 48 && mod
->mAmtSrcOp
== 0 && mod
->mTransOp
== 0)
485 VECTOR_BACK(self
->mods
).mAmount
+= 960;
486 else if(mod
->mSrcOp
== 0x00DB && mod
->mDstOp
== 16 && mod
->mAmtSrcOp
== 0 && mod
->mTransOp
== 0)
487 VECTOR_BACK(self
->mods
).mAmount
+= 200;
488 else if(mod
->mSrcOp
== 0x00DD && mod
->mDstOp
== 15 && mod
->mAmtSrcOp
== 0 && mod
->mTransOp
== 0)
489 VECTOR_BACK(self
->mods
).mAmount
+= 200;
490 /*else if(mod->mSrcOp == 0x020E && mod->mDstOp == ?initialpitch? && mod->mAmtSrcOp == 0x0010 && mod->mTransOp == 0)
491 VECTOR_BACK(self->mods).mAmount += 12700;*/
495 #define ERROR_GOTO(lbl_, ...) do { \
500 static ALboolean
ensureFontSanity(const Soundfont
*sfont
)
504 for(i
= 0;i
< sfont
->phdr_size
-1;i
++)
506 if(sfont
->phdr
[i
].mZoneIdx
>= sfont
->pbag_size
)
508 WARN("Preset %d has invalid zone index %d (max: %d)\n", i
,
509 sfont
->phdr
[i
].mZoneIdx
, sfont
->pbag_size
);
512 if(sfont
->phdr
[i
+1].mZoneIdx
< sfont
->phdr
[i
].mZoneIdx
)
514 WARN("Preset %d has invalid zone index (%d does not follow %d)\n", i
+1,
515 sfont
->phdr
[i
+1].mZoneIdx
, sfont
->phdr
[i
].mZoneIdx
);
519 if(sfont
->phdr
[i
].mZoneIdx
>= sfont
->pbag_size
)
521 WARN("Preset %d has invalid zone index %d (max: %d)\n", i
,
522 sfont
->phdr
[i
].mZoneIdx
, sfont
->pbag_size
);
526 for(i
= 0;i
< sfont
->pbag_size
-1;i
++)
528 if(sfont
->pbag
[i
].mGenIdx
>= sfont
->pgen_size
)
530 WARN("Preset zone %d has invalid generator index %d (max: %d)\n", i
,
531 sfont
->pbag
[i
].mGenIdx
, sfont
->pgen_size
);
534 if(sfont
->pbag
[i
+1].mGenIdx
< sfont
->pbag
[i
].mGenIdx
)
536 WARN("Preset zone %d has invalid generator index (%d does not follow %d)\n", i
+1,
537 sfont
->pbag
[i
+1].mGenIdx
, sfont
->pbag
[i
].mGenIdx
);
540 if(sfont
->pbag
[i
].mModIdx
>= sfont
->pmod_size
)
542 WARN("Preset zone %d has invalid modulator index %d (max: %d)\n", i
,
543 sfont
->pbag
[i
].mModIdx
, sfont
->pmod_size
);
546 if(sfont
->pbag
[i
+1].mModIdx
< sfont
->pbag
[i
].mModIdx
)
548 WARN("Preset zone %d has invalid modulator index (%d does not follow %d)\n", i
+1,
549 sfont
->pbag
[i
+1].mModIdx
, sfont
->pbag
[i
].mModIdx
);
553 if(sfont
->pbag
[i
].mGenIdx
>= sfont
->pgen_size
)
555 WARN("Preset zone %d has invalid generator index %d (max: %d)\n", i
,
556 sfont
->pbag
[i
].mGenIdx
, sfont
->pgen_size
);
559 if(sfont
->pbag
[i
].mModIdx
>= sfont
->pmod_size
)
561 WARN("Preset zone %d has invalid modulator index %d (max: %d)\n", i
,
562 sfont
->pbag
[i
].mModIdx
, sfont
->pmod_size
);
567 for(i
= 0;i
< sfont
->inst_size
-1;i
++)
569 if(sfont
->inst
[i
].mZoneIdx
>= sfont
->ibag_size
)
571 WARN("Instrument %d has invalid zone index %d (max: %d)\n", i
,
572 sfont
->inst
[i
].mZoneIdx
, sfont
->ibag_size
);
575 if(sfont
->inst
[i
+1].mZoneIdx
< sfont
->inst
[i
].mZoneIdx
)
577 WARN("Instrument %d has invalid zone index (%d does not follow %d)\n", i
+1,
578 sfont
->inst
[i
+1].mZoneIdx
, sfont
->inst
[i
].mZoneIdx
);
582 if(sfont
->inst
[i
].mZoneIdx
>= sfont
->ibag_size
)
584 WARN("Instrument %d has invalid zone index %d (max: %d)\n", i
,
585 sfont
->inst
[i
].mZoneIdx
, sfont
->ibag_size
);
589 for(i
= 0;i
< sfont
->ibag_size
-1;i
++)
591 if(sfont
->ibag
[i
].mGenIdx
>= sfont
->igen_size
)
593 WARN("Instrument zone %d has invalid generator index %d (max: %d)\n", i
,
594 sfont
->ibag
[i
].mGenIdx
, sfont
->igen_size
);
597 if(sfont
->ibag
[i
+1].mGenIdx
< sfont
->ibag
[i
].mGenIdx
)
599 WARN("Instrument zone %d has invalid generator index (%d does not follow %d)\n", i
+1,
600 sfont
->ibag
[i
+1].mGenIdx
, sfont
->ibag
[i
].mGenIdx
);
603 if(sfont
->ibag
[i
].mModIdx
>= sfont
->imod_size
)
605 WARN("Instrument zone %d has invalid modulator index %d (max: %d)\n", i
,
606 sfont
->ibag
[i
].mModIdx
, sfont
->imod_size
);
609 if(sfont
->ibag
[i
+1].mModIdx
< sfont
->ibag
[i
].mModIdx
)
611 WARN("Instrument zone %d has invalid modulator index (%d does not follow %d)\n", i
+1,
612 sfont
->ibag
[i
+1].mModIdx
, sfont
->ibag
[i
].mModIdx
);
616 if(sfont
->ibag
[i
].mGenIdx
>= sfont
->igen_size
)
618 WARN("Instrument zone %d has invalid generator index %d (max: %d)\n", i
,
619 sfont
->ibag
[i
].mGenIdx
, sfont
->igen_size
);
622 if(sfont
->ibag
[i
].mModIdx
>= sfont
->imod_size
)
624 WARN("Instrument zone %d has invalid modulator index %d (max: %d)\n", i
,
625 sfont
->ibag
[i
].mModIdx
, sfont
->imod_size
);
630 for(i
= 0;i
< sfont
->shdr_size
-1;i
++)
632 if((sfont
->shdr
[i
].mSampleType
&0x8000) && sfont
->irom
== NULL
)
634 WARN("Sample header %d has ROM sample type without an irom sub-chunk\n", i
);
643 static ALboolean
checkZone(const GenModList
*zone
, const PresetHeader
*preset
, const InstrumentHeader
*inst
, const SampleHeader
*samp
)
645 Generator
*gen
= VECTOR_ITER_BEGIN(zone
->gens
);
646 Generator
*gen_end
= VECTOR_ITER_END(zone
->gens
);
647 for(;gen
!= gen_end
;gen
++)
649 if(gen
->mGenerator
== 43 || gen
->mGenerator
== 44)
651 int high
= gen
->mAmount
>>8;
652 int low
= gen
->mAmount
&0xff;
654 if(!(low
>= 0 && high
<= 127 && high
>= low
))
656 TRACE("Preset \"%s\", inst \"%s\", sample \"%s\": invalid %s range %d...%d\n",
657 preset
->mName
, inst
->mName
, samp
->mName
,
658 (gen
->mGenerator
== 43) ? "key" :
659 (gen
->mGenerator
== 44) ? "velocity" : "(unknown)",
669 static ALenum
getModSrcInput(int input
)
671 if(input
== 0) return AL_ONE_SOFT
;
672 if(input
== 2) return AL_NOTEON_VELOCITY_SOFT
;
673 if(input
== 3) return AL_NOTEON_KEY_SOFT
;
674 if(input
== 10) return AL_KEYPRESSURE_SOFT
;
675 if(input
== 13) return AL_CHANNELPRESSURE_SOFT
;
676 if(input
== 14) return AL_PITCHBEND_SOFT
;
677 if(input
== 16) return AL_PITCHBEND_SENSITIVITY_SOFT
;
681 if(input
> 0 && input
< 120 && !(input
== 6 || (input
>= 32 && input
<= 63) ||
682 (input
>= 98 && input
<= 101)))
686 ERR("Unhandled modulator source input: 0x%02x\n", input
);
690 static ALenum
getModSrcType(int type
)
692 if(type
== 0x0000) return AL_UNORM_SOFT
;
693 if(type
== 0x0100) return AL_UNORM_REV_SOFT
;
694 if(type
== 0x0200) return AL_SNORM_SOFT
;
695 if(type
== 0x0300) return AL_SNORM_REV_SOFT
;
696 ERR("Unhandled modulator source type: 0x%04x\n", type
);
700 static ALenum
getModSrcForm(int form
)
702 if(form
== 0x0000) return AL_LINEAR_SOFT
;
703 if(form
== 0x0400) return AL_CONCAVE_SOFT
;
704 if(form
== 0x0800) return AL_CONVEX_SOFT
;
705 if(form
== 0x0C00) return AL_SWITCH_SOFT
;
706 ERR("Unhandled modulator source form: 0x%04x\n", form
);
710 static ALenum
getModTransOp(int op
)
712 if(op
== 0) return AL_LINEAR_SOFT
;
713 if(op
== 2) return AL_ABSOLUTE_SOFT
;
714 ERR("Unhandled modulator transform op: 0x%04x\n", op
);
718 static ALenum
getLoopMode(int mode
)
720 if(mode
== 0) return AL_NONE
;
721 if(mode
== 1) return AL_LOOP_CONTINUOUS_SOFT
;
722 if(mode
== 3) return AL_LOOP_UNTIL_RELEASE_SOFT
;
723 ERR("Unhandled loop mode: %d\n", mode
);
727 static ALenum
getSampleType(int type
)
729 if(type
== 1) return AL_MONO_SOFT
;
730 if(type
== 2) return AL_RIGHT_SOFT
;
731 if(type
== 4) return AL_LEFT_SOFT
;
734 WARN("Sample type \"linked\" ignored; pretending mono\n");
737 ERR("Unhandled sample type: 0x%04x\n", type
);
741 static void fillZone(ALfontsound
*sound
, ALCcontext
*context
, const GenModList
*zone
)
743 static const ALenum Gen2Param
[60] = {
744 0, /* 0 - startAddrOffset */
745 0, /* 1 - endAddrOffset */
746 0, /* 2 - startloopAddrOffset */
747 0, /* 3 - endloopAddrOffset */
748 0, /* 4 - startAddrCoarseOffset */
749 AL_MOD_LFO_TO_PITCH_SOFT
, /* 5 - modLfoToPitch */
750 AL_VIBRATO_LFO_TO_PITCH_SOFT
, /* 6 - vibLfoToPitch */
751 AL_MOD_ENV_TO_PITCH_SOFT
, /* 7 - modEnvToPitch */
752 AL_FILTER_CUTOFF_SOFT
, /* 8 - initialFilterFc */
753 AL_FILTER_RESONANCE_SOFT
, /* 9 - initialFilterQ */
754 AL_MOD_LFO_TO_FILTER_CUTOFF_SOFT
, /* 10 - modLfoToFilterFc */
755 AL_MOD_ENV_TO_FILTER_CUTOFF_SOFT
, /* 11 - modEnvToFilterFc */
756 0, /* 12 - endAddrCoarseOffset */
757 AL_MOD_LFO_TO_VOLUME_SOFT
, /* 13 - modLfoToVolume */
759 AL_CHORUS_SEND_SOFT
, /* 15 - chorusEffectsSend */
760 AL_REVERB_SEND_SOFT
, /* 16 - reverbEffectsSend */
761 AL_PAN_SOFT
, /* 17 - pan */
765 AL_MOD_LFO_DELAY_SOFT
, /* 21 - delayModLFO */
766 AL_MOD_LFO_FREQUENCY_SOFT
, /* 22 - freqModLFO */
767 AL_VIBRATO_LFO_DELAY_SOFT
, /* 23 - delayVibLFO */
768 AL_VIBRATO_LFO_FREQUENCY_SOFT
, /* 24 - freqVibLFO */
769 AL_MOD_ENV_DELAYTIME_SOFT
, /* 25 - delayModEnv */
770 AL_MOD_ENV_ATTACKTIME_SOFT
, /* 26 - attackModEnv */
771 AL_MOD_ENV_HOLDTIME_SOFT
, /* 27 - holdModEnv */
772 AL_MOD_ENV_DECAYTIME_SOFT
, /* 28 - decayModEnv */
773 AL_MOD_ENV_SUSTAINVOLUME_SOFT
, /* 29 - sustainModEnv */
774 AL_MOD_ENV_RELEASETIME_SOFT
, /* 30 - releaseModEnv */
775 AL_MOD_ENV_KEY_TO_HOLDTIME_SOFT
, /* 31 - keynumToModEnvHold */
776 AL_MOD_ENV_KEY_TO_DECAYTIME_SOFT
, /* 32 - keynumToModEnvDecay */
777 AL_VOLUME_ENV_DELAYTIME_SOFT
, /* 33 - delayVolEnv */
778 AL_VOLUME_ENV_ATTACKTIME_SOFT
, /* 34 - attackVolEnv */
779 AL_VOLUME_ENV_HOLDTIME_SOFT
, /* 35 - holdVolEnv */
780 AL_VOLUME_ENV_DECAYTIME_SOFT
, /* 36 - decayVolEnv */
781 AL_VOLUME_ENV_SUSTAINVOLUME_SOFT
, /* 37 - sustainVolEnv */
782 AL_VOLUME_ENV_RELEASETIME_SOFT
, /* 38 - releaseVolEnv */
783 AL_VOLUME_ENV_KEY_TO_HOLDTIME_SOFT
, /* 39 - keynumToVolEnvHold */
784 AL_VOLUME_ENV_KEY_TO_DECAYTIME_SOFT
, /* 40 - keynumToVolEnvDecay */
787 AL_KEY_RANGE_SOFT
, /* 43 - keyRange */
788 AL_VELOCITY_RANGE_SOFT
, /* 44 - velRange */
789 0, /* 45 - startloopAddrCoarseOffset */
791 0, /* 47 - velocity */
792 AL_ATTENUATION_SOFT
, /* 48 - initialAttenuation */
794 0, /* 50 - endloopAddrCoarseOffset */
795 AL_TUNING_COARSE_SOFT
, /* 51 - corseTune */
796 AL_TUNING_FINE_SOFT
, /* 52 - fineTune */
798 AL_LOOP_MODE_SOFT
, /* 54 - sampleModes */
800 AL_TUNING_SCALE_SOFT
, /* 56 - scaleTuning */
801 AL_EXCLUSIVE_CLASS_SOFT
, /* 57 - exclusiveClass */
802 AL_BASE_KEY_SOFT
, /* 58 - overridingRootKey */
805 const Generator
*gen
, *gen_end
;
806 const Modulator
*mod
, *mod_end
;
808 mod
= VECTOR_ITER_BEGIN(zone
->mods
);
809 mod_end
= VECTOR_ITER_END(zone
->mods
);
810 for(;mod
!= mod_end
;mod
++)
812 ALenum src0in
= getModSrcInput(mod
->mSrcOp
&0xFF);
813 ALenum src0type
= getModSrcType(mod
->mSrcOp
&0x0300);
814 ALenum src0form
= getModSrcForm(mod
->mSrcOp
&0xFC00);
815 ALenum src1in
= getModSrcInput(mod
->mAmtSrcOp
&0xFF);
816 ALenum src1type
= getModSrcType(mod
->mAmtSrcOp
&0x0300);
817 ALenum src1form
= getModSrcForm(mod
->mAmtSrcOp
&0xFC00);
818 ALenum trans
= getModTransOp(mod
->mTransOp
);
819 ALenum dst
= (mod
->mDstOp
< 60) ? Gen2Param
[mod
->mDstOp
] : 0;
820 if(!dst
|| dst
== AL_KEY_RANGE_SOFT
|| dst
== AL_VELOCITY_RANGE_SOFT
||
821 dst
== AL_LOOP_MODE_SOFT
|| dst
== AL_EXCLUSIVE_CLASS_SOFT
||
822 dst
== AL_BASE_KEY_SOFT
)
823 ERR("Unhandled modulator destination: %d\n", mod
->mDstOp
);
824 else if(src0in
!= AL_INVALID
&& src0form
!= AL_INVALID
&& src0type
!= AL_INVALID
&&
825 src1in
!= AL_INVALID
&& src1form
!= AL_INVALID
&& src0type
!= AL_INVALID
&&
828 ALsizei idx
= mod
- VECTOR_ITER_BEGIN(zone
->mods
);
829 ALfontsound_setModStagei(sound
, context
, idx
, AL_SOURCE0_INPUT_SOFT
, src0in
);
830 ALfontsound_setModStagei(sound
, context
, idx
, AL_SOURCE0_TYPE_SOFT
, src0type
);
831 ALfontsound_setModStagei(sound
, context
, idx
, AL_SOURCE0_FORM_SOFT
, src0form
);
832 ALfontsound_setModStagei(sound
, context
, idx
, AL_SOURCE1_INPUT_SOFT
, src1in
);
833 ALfontsound_setModStagei(sound
, context
, idx
, AL_SOURCE1_TYPE_SOFT
, src1type
);
834 ALfontsound_setModStagei(sound
, context
, idx
, AL_SOURCE1_FORM_SOFT
, src1form
);
835 ALfontsound_setModStagei(sound
, context
, idx
, AL_AMOUNT_SOFT
, mod
->mAmount
);
836 ALfontsound_setModStagei(sound
, context
, idx
, AL_TRANSFORM_OP_SOFT
, trans
);
837 ALfontsound_setModStagei(sound
, context
, idx
, AL_DESTINATION_SOFT
, dst
);
841 gen
= VECTOR_ITER_BEGIN(zone
->gens
);
842 gen_end
= VECTOR_ITER_END(zone
->gens
);
843 for(;gen
!= gen_end
;gen
++)
845 ALint value
= (ALshort
)gen
->mAmount
;
846 if(gen
->mGenerator
== 0)
847 sound
->Start
+= value
;
848 else if(gen
->mGenerator
== 1)
850 else if(gen
->mGenerator
== 2)
851 sound
->LoopStart
+= value
;
852 else if(gen
->mGenerator
== 3)
853 sound
->LoopEnd
+= value
;
854 else if(gen
->mGenerator
== 4)
855 sound
->Start
+= value
<<15;
856 else if(gen
->mGenerator
== 12)
857 sound
->End
+= value
<<15;
858 else if(gen
->mGenerator
== 45)
859 sound
->LoopStart
+= value
<<15;
860 else if(gen
->mGenerator
== 50)
861 sound
->LoopEnd
+= value
<<15;
862 else if(gen
->mGenerator
== 43)
864 sound
->MinKey
= mini((value
&0xff), 127);
865 sound
->MaxKey
= mini(((value
>>8)&0xff), 127);
867 else if(gen
->mGenerator
== 44)
869 sound
->MinVelocity
= mini((value
&0xff), 127);
870 sound
->MaxVelocity
= mini(((value
>>8)&0xff), 127);
875 if(gen
->mGenerator
< 60)
876 param
= Gen2Param
[gen
->mGenerator
];
879 if(param
== AL_BASE_KEY_SOFT
)
881 if(!(value
>= 0 && value
<= 127))
884 WARN("Invalid overridingRootKey generator value %d\n", value
);
888 if(param
== AL_FILTER_RESONANCE_SOFT
|| param
== AL_ATTENUATION_SOFT
)
889 value
= maxi(0, value
);
890 else if(param
== AL_CHORUS_SEND_SOFT
|| param
== AL_REVERB_SEND_SOFT
)
891 value
= clampi(value
, 0, 1000);
892 else if(param
== AL_LOOP_MODE_SOFT
)
893 value
= getLoopMode(value
);
894 ALfontsound_setPropi(sound
, context
, param
, value
);
896 else if(gen
->mGenerator
< 256)
898 static ALboolean warned
[256];
899 if(!warned
[gen
->mGenerator
])
901 warned
[gen
->mGenerator
] = AL_TRUE
;
902 ERR("Unhandled generator %d\n", gen
->mGenerator
);
909 static void processInstrument(ALfontsound
***sounds
, ALsizei
*sounds_size
, ALCcontext
*context
, InstrumentHeader
*inst
, const PresetHeader
*preset
, const Soundfont
*sfont
, const GenModList
*pzone
)
911 const Generator
*gen
, *gen_end
;
912 const Modulator
*mod
, *mod_end
;
913 const Zone
*zone
, *zone_end
;
917 if((inst
+1)->mZoneIdx
== inst
->mZoneIdx
)
918 ERR("Instrument with no zones!");
920 GenModList_Construct(&gzone
);
921 zone
= sfont
->ibag
+ inst
->mZoneIdx
;
922 zone_end
= sfont
->ibag
+ (inst
+1)->mZoneIdx
;
923 if(zone_end
-zone
> 1)
925 gen
= sfont
->igen
+ zone
->mGenIdx
;
926 gen_end
= sfont
->igen
+ (zone
+1)->mGenIdx
;
928 // If no generators, or last generator is not a sample, this is a global zone
929 for(;gen
!= gen_end
;gen
++)
931 if(gen
->mGenerator
== 53)
937 gen
= sfont
->igen
+ zone
->mGenIdx
;
938 gen_end
= sfont
->igen
+ (zone
+1)->mGenIdx
;
939 for(;gen
!= gen_end
;gen
++)
940 GenModList_insertGen(&gzone
, gen
, AL_FALSE
);
942 mod
= sfont
->imod
+ zone
->mModIdx
;
943 mod_end
= sfont
->imod
+ (zone
+1)->mModIdx
;
944 for(;mod
!= mod_end
;mod
++)
945 GenModList_insertMod(&gzone
, mod
);
951 temp
= realloc(*sounds
, (zone_end
-zone
+ *sounds_size
)*sizeof((*sounds
)[0]));
954 ERR("Failed reallocating fontsound storage to %d elements (from %d)\n",
955 (ALsizei
)(zone_end
-zone
) + *sounds_size
, *sounds_size
);
959 for(;zone
!= zone_end
;zone
++)
961 GenModList lzone
= GenModList_clone(&gzone
);
962 mod
= sfont
->imod
+ zone
->mModIdx
;
963 mod_end
= sfont
->imod
+ (zone
+1)->mModIdx
;
964 for(;mod
!= mod_end
;mod
++)
965 GenModList_insertMod(&lzone
, mod
);
967 gen
= sfont
->igen
+ zone
->mGenIdx
;
968 gen_end
= sfont
->igen
+ (zone
+1)->mGenIdx
;
969 for(;gen
!= gen_end
;gen
++)
971 if(gen
->mGenerator
== 53)
973 const SampleHeader
*samp
;
976 if(gen
->mAmount
>= sfont
->shdr_size
-1)
978 ERR("Generator %ld has invalid sample ID (%d of %d)\n",
979 (long)(gen
-sfont
->igen
), gen
->mAmount
, sfont
->shdr_size
-1);
982 samp
= &sfont
->shdr
[gen
->mAmount
];
984 gen
= VECTOR_ITER_BEGIN(pzone
->gens
);
985 gen_end
= VECTOR_ITER_END(pzone
->gens
);
986 for(;gen
!= gen_end
;gen
++)
987 GenModList_accumGen(&lzone
, gen
);
989 mod
= VECTOR_ITER_BEGIN(pzone
->mods
);
990 mod_end
= VECTOR_ITER_END(pzone
->mods
);
991 for(;mod
!= mod_end
;mod
++)
992 GenModList_accumMod(&lzone
, mod
);
994 if(!checkZone(&lzone
, preset
, inst
, samp
))
996 /* Ignore ROM samples for now. */
997 if((samp
->mSampleType
&0x8000))
1000 sound
= NewFontsound(context
);
1001 (*sounds
)[(*sounds_size
)++] = sound
;
1002 ALfontsound_setPropi(sound
, context
, AL_SAMPLE_START_SOFT
, samp
->mStart
);
1003 ALfontsound_setPropi(sound
, context
, AL_SAMPLE_END_SOFT
, samp
->mEnd
);
1004 ALfontsound_setPropi(sound
, context
, AL_SAMPLE_LOOP_START_SOFT
, samp
->mStartloop
);
1005 ALfontsound_setPropi(sound
, context
, AL_SAMPLE_LOOP_END_SOFT
, samp
->mEndloop
);
1006 ALfontsound_setPropi(sound
, context
, AL_SAMPLE_RATE_SOFT
, samp
->mSampleRate
);
1007 ALfontsound_setPropi(sound
, context
, AL_BASE_KEY_SOFT
, (samp
->mOriginalKey
<= 127) ? samp
->mOriginalKey
: 60);
1008 ALfontsound_setPropi(sound
, context
, AL_KEY_CORRECTION_SOFT
, samp
->mCorrection
);
1009 ALfontsound_setPropi(sound
, context
, AL_SAMPLE_TYPE_SOFT
, getSampleType(samp
->mSampleType
&0x7fff));
1010 fillZone(sound
, context
, &lzone
);
1014 GenModList_insertGen(&lzone
, gen
, AL_FALSE
);
1017 GenModList_Destruct(&lzone
);
1020 GenModList_Destruct(&gzone
);
1023 ALboolean
loadSf2(Reader
*stream
, ALsoundfont
*soundfont
, ALCcontext
*context
)
1025 ALsfpreset
**presets
= NULL
;
1026 ALsizei presets_size
= 0;
1033 Soundfont_Construct(&sfont
);
1035 RiffHdr_read(&riff
, stream
);
1036 if(riff
.mCode
!= FOURCC('R','I','F','F'))
1037 ERROR_GOTO(error
, "Invalid Format, expected RIFF got '%c%c%c%c'\n", FOURCCARGS(riff
.mCode
));
1038 if((ltype
=read_le32(stream
)) != FOURCC('s','f','b','k'))
1039 ERROR_GOTO(error
, "Invalid Format, expected sfbk got '%c%c%c%c'\n", FOURCCARGS(ltype
));
1041 if(READERR(stream
) != 0)
1042 ERROR_GOTO(error
, "Error reading file header\n");
1044 RiffHdr_read(&list
, stream
);
1045 if(list
.mCode
!= FOURCC('L','I','S','T'))
1046 ERROR_GOTO(error
, "Invalid Format, expected LIST (INFO) got '%c%c%c%c'\n", FOURCCARGS(list
.mCode
));
1047 if((ltype
=read_le32(stream
)) != FOURCC('I','N','F','O'))
1048 ERROR_GOTO(error
, "Invalid Format, expected INFO got '%c%c%c%c'\n", FOURCCARGS(ltype
));
1050 while(list
.mSize
> 0 && !READERR(stream
))
1054 RiffHdr_read(&info
, stream
);
1056 if(info
.mCode
== FOURCC('i','f','i','l'))
1059 ERR("Invalid ifil chunk size: %d\n", info
.mSize
);
1062 ALushort major
= read_le16(stream
);
1063 ALushort minor
= read_le16(stream
);
1069 ERROR_GOTO(error
, "Unsupported SF2 format version: %d.%02d\n", major
, minor
);
1070 TRACE("SF2 format version: %d.%02d\n", major
, minor
);
1072 sfont
.ifil
= (major
<<16) | minor
;
1075 else if(info
.mCode
== FOURCC('i','r','o','m'))
1077 if(info
.mSize
== 0 || (info
.mSize
&1))
1078 ERR("Invalid irom size: %d\n", info
.mSize
);
1082 sfont
.irom
= calloc(1, info
.mSize
+1);
1083 READ(stream
, sfont
.irom
, info
.mSize
);
1085 list
.mSize
-= info
.mSize
;
1086 info
.mSize
-= info
.mSize
;
1088 TRACE("SF2 ROM ID: %s\n", sfont
.irom
);
1091 list
.mSize
-= info
.mSize
;
1092 skip(stream
, info
.mSize
);
1095 if(READERR(stream
) != 0)
1096 ERROR_GOTO(error
, "Error reading INFO chunk\n");
1098 ERROR_GOTO(error
, "Missing ifil sub-chunk\n");
1100 RiffHdr_read(&list
, stream
);
1101 if(list
.mCode
!= FOURCC('L','I','S','T'))
1102 ERROR_GOTO(error
, "Invalid Format, expected LIST (sdta) got '%c%c%c%c'\n", FOURCCARGS(list
.mCode
));
1103 if((ltype
=read_le32(stream
)) != FOURCC('s','d','t','a'))
1104 ERROR_GOTO(error
, "Invalid Format, expected sdta got '%c%c%c%c'\n", FOURCCARGS(ltype
));
1110 RiffHdr_read(&smpl
, stream
);
1111 if(smpl
.mCode
!= FOURCC('s','m','p','l'))
1112 ERROR_GOTO(error
, "Invalid Format, expected smpl got '%c%c%c%c'\n", FOURCCARGS(smpl
.mCode
));
1115 if(smpl
.mSize
> list
.mSize
)
1116 ERROR_GOTO(error
, "Invalid Format, sample chunk size mismatch\n");
1118 if(!(ptr
=realloc(soundfont
->Samples
, smpl
.mSize
)))
1119 SET_ERROR_AND_GOTO(context
, AL_OUT_OF_MEMORY
, error
);
1120 soundfont
->Samples
= (ALshort
*)ptr
;
1121 soundfont
->NumSamples
= smpl
.mSize
/2;
1123 if(IS_LITTLE_ENDIAN
)
1124 READ(stream
, ptr
, smpl
.mSize
);
1128 while(total
< smpl
.mSize
)
1131 ALuint todo
= minu(smpl
.mSize
-total
, sizeof(buf
));
1134 READ(stream
, buf
, todo
);
1135 for(i
= 0;i
< todo
;i
++)
1136 ptr
[total
+i
] = buf
[i
^1];
1141 list
.mSize
-= smpl
.mSize
;
1143 skip(stream
, list
.mSize
);
1146 if(READERR(stream
) != 0)
1147 ERROR_GOTO(error
, "Error reading sdta chunk\n");
1149 RiffHdr_read(&list
, stream
);
1150 if(list
.mCode
!= FOURCC('L','I','S','T'))
1151 ERROR_GOTO(error
, "Invalid Format, expected LIST (pdta) got '%c%c%c%c'\n", FOURCCARGS(list
.mCode
));
1152 if((ltype
=read_le32(stream
)) != FOURCC('p','d','t','a'))
1153 ERROR_GOTO(error
, "Invalid Format, expected pdta got '%c%c%c%c'\n", FOURCCARGS(ltype
));
1156 RiffHdr_read(&list
, stream
);
1157 if(list
.mCode
!= FOURCC('p','h','d','r'))
1158 ERROR_GOTO(error
, "Invalid Format, expected phdr got '%c%c%c%c'\n", FOURCCARGS(list
.mCode
));
1159 if((list
.mSize
%38) != 0 || list
.mSize
== 0)
1160 ERROR_GOTO(error
, "Invalid Format, bad phdr size: %u\n", list
.mSize
);
1161 sfont
.phdr_size
= list
.mSize
/38;
1162 sfont
.phdr
= calloc(sfont
.phdr_size
, sizeof(sfont
.phdr
[0]));
1163 for(i
= 0;i
< sfont
.phdr_size
;i
++)
1164 PresetHeader_read(&sfont
.phdr
[i
], stream
);
1166 RiffHdr_read(&list
, stream
);
1167 if(list
.mCode
!= FOURCC('p','b','a','g'))
1168 ERROR_GOTO(error
, "Invalid Format, expected pbag got '%c%c%c%c'\n", FOURCCARGS(list
.mCode
));
1169 if((list
.mSize
%4) != 0 || list
.mSize
== 0)
1170 ERROR_GOTO(error
, "Invalid Format, bad pbag size: %u\n", list
.mSize
);
1171 sfont
.pbag_size
= list
.mSize
/4;
1172 sfont
.pbag
= calloc(sfont
.pbag_size
, sizeof(sfont
.pbag
[0]));
1173 for(i
= 0;i
< sfont
.pbag_size
;i
++)
1174 Zone_read(&sfont
.pbag
[i
], stream
);
1176 RiffHdr_read(&list
, stream
);
1177 if(list
.mCode
!= FOURCC('p','m','o','d'))
1178 ERROR_GOTO(error
, "Invalid Format, expected pmod got '%c%c%c%c'\n", FOURCCARGS(list
.mCode
));
1179 if((list
.mSize
%10) != 0 || list
.mSize
== 0)
1180 ERROR_GOTO(error
, "Invalid Format, bad pmod size: %u\n", list
.mSize
);
1181 sfont
.pmod_size
= list
.mSize
/10;
1182 sfont
.pmod
= calloc(sfont
.pmod_size
, sizeof(sfont
.pmod
[0]));
1183 for(i
= 0;i
< sfont
.pmod_size
;i
++)
1184 Modulator_read(&sfont
.pmod
[i
], stream
);
1186 RiffHdr_read(&list
, stream
);
1187 if(list
.mCode
!= FOURCC('p','g','e','n'))
1188 ERROR_GOTO(error
, "Invalid Format, expected pgen got '%c%c%c%c'\n", FOURCCARGS(list
.mCode
));
1189 if((list
.mSize
%4) != 0 || list
.mSize
== 0)
1190 ERROR_GOTO(error
, "Invalid Format, bad pgen size: %u\n", list
.mSize
);
1191 sfont
.pgen_size
= list
.mSize
/4;
1192 sfont
.pgen
= calloc(sfont
.pgen_size
, sizeof(sfont
.pgen
[0]));
1193 for(i
= 0;i
< sfont
.pgen_size
;i
++)
1194 Generator_read(&sfont
.pgen
[i
], stream
);
1197 RiffHdr_read(&list
, stream
);
1198 if(list
.mCode
!= FOURCC('i','n','s','t'))
1199 ERROR_GOTO(error
, "Invalid Format, expected inst got '%c%c%c%c'\n", FOURCCARGS(list
.mCode
));
1200 if((list
.mSize
%22) != 0 || list
.mSize
== 0)
1201 ERROR_GOTO(error
, "Invalid Format, bad inst size: %u\n", list
.mSize
);
1202 sfont
.inst_size
= list
.mSize
/22;
1203 sfont
.inst
= calloc(sfont
.inst_size
, sizeof(sfont
.inst
[0]));
1204 for(i
= 0;i
< sfont
.inst_size
;i
++)
1205 InstrumentHeader_read(&sfont
.inst
[i
], stream
);
1207 RiffHdr_read(&list
, stream
);
1208 if(list
.mCode
!= FOURCC('i','b','a','g'))
1209 ERROR_GOTO(error
, "Invalid Format, expected ibag got '%c%c%c%c'\n", FOURCCARGS(list
.mCode
));
1210 if((list
.mSize
%4) != 0 || list
.mSize
== 0)
1211 ERROR_GOTO(error
, "Invalid Format, bad ibag size: %u\n", list
.mSize
);
1212 sfont
.ibag_size
= list
.mSize
/4;
1213 sfont
.ibag
= calloc(sfont
.ibag_size
, sizeof(sfont
.ibag
[0]));
1214 for(i
= 0;i
< sfont
.ibag_size
;i
++)
1215 Zone_read(&sfont
.ibag
[i
], stream
);
1217 RiffHdr_read(&list
, stream
);
1218 if(list
.mCode
!= FOURCC('i','m','o','d'))
1219 ERROR_GOTO(error
, "Invalid Format, expected imod got '%c%c%c%c'\n", FOURCCARGS(list
.mCode
));
1220 if((list
.mSize
%10) != 0 || list
.mSize
== 0)
1221 ERROR_GOTO(error
, "Invalid Format, bad imod size: %u\n", list
.mSize
);
1222 sfont
.imod_size
= list
.mSize
/10;
1223 sfont
.imod
= calloc(sfont
.imod_size
, sizeof(sfont
.imod
[0]));
1224 for(i
= 0;i
< sfont
.imod_size
;i
++)
1225 Modulator_read(&sfont
.imod
[i
], stream
);
1227 RiffHdr_read(&list
, stream
);
1228 if(list
.mCode
!= FOURCC('i','g','e','n'))
1229 ERROR_GOTO(error
, "Invalid Format, expected igen got '%c%c%c%c'\n", FOURCCARGS(list
.mCode
));
1230 if((list
.mSize
%4) != 0 || list
.mSize
== 0)
1231 ERROR_GOTO(error
, "Invalid Format, bad igen size: %u\n", list
.mSize
);
1232 sfont
.igen_size
= list
.mSize
/4;
1233 sfont
.igen
= calloc(sfont
.igen_size
, sizeof(sfont
.igen
[0]));
1234 for(i
= 0;i
< sfont
.igen_size
;i
++)
1235 Generator_read(&sfont
.igen
[i
], stream
);
1238 RiffHdr_read(&list
, stream
);
1239 if(list
.mCode
!= FOURCC('s','h','d','r'))
1240 ERROR_GOTO(error
, "Invalid Format, expected shdr got '%c%c%c%c'\n", FOURCCARGS(list
.mCode
));
1241 if((list
.mSize
%46) != 0 || list
.mSize
== 0)
1242 ERROR_GOTO(error
, "Invalid Format, bad shdr size: %u\n", list
.mSize
);
1243 sfont
.shdr_size
= list
.mSize
/46;
1244 sfont
.shdr
= calloc(sfont
.shdr_size
, sizeof(sfont
.shdr
[0]));
1245 for(i
= 0;i
< sfont
.shdr_size
;i
++)
1246 SampleHeader_read(&sfont
.shdr
[i
], stream
);
1248 if(READERR(stream
) != 0)
1249 ERROR_GOTO(error
, "Error reading pdta chunk\n");
1251 if(!ensureFontSanity(&sfont
))
1254 presets
= calloc(1, (sfont
.phdr_size
-1)*sizeof(presets
[0]));
1256 ERROR_GOTO(error
, "Error allocating presets\n");
1258 for(i
= 0;i
< sfont
.phdr_size
-1;i
++)
1260 const Generator
*gen
, *gen_end
;
1261 const Modulator
*mod
, *mod_end
;
1262 const Zone
*zone
, *zone_end
;
1263 ALfontsound
**sounds
= NULL
;
1264 ALsizei sounds_size
= 0;
1267 if(sfont
.phdr
[i
+1].mZoneIdx
== sfont
.phdr
[i
].mZoneIdx
)
1270 GenModList_Construct(&gzone
);
1271 zone
= sfont
.pbag
+ sfont
.phdr
[i
].mZoneIdx
;
1272 zone_end
= sfont
.pbag
+ sfont
.phdr
[i
+1].mZoneIdx
;
1273 if(zone_end
-zone
> 1)
1275 gen
= sfont
.pgen
+ zone
->mGenIdx
;
1276 gen_end
= sfont
.pgen
+ (zone
+1)->mGenIdx
;
1278 // If no generators, or last generator is not an instrument, this is a global zone
1279 for(;gen
!= gen_end
;gen
++)
1281 if(gen
->mGenerator
== 41)
1287 gen
= sfont
.pgen
+ zone
->mGenIdx
;
1288 gen_end
= sfont
.pgen
+ (zone
+1)->mGenIdx
;
1289 for(;gen
!= gen_end
;gen
++)
1290 GenModList_insertGen(&gzone
, gen
, AL_TRUE
);
1292 mod
= sfont
.pmod
+ zone
->mModIdx
;
1293 mod_end
= sfont
.pmod
+ (zone
+1)->mModIdx
;
1294 for(;mod
!= mod_end
;mod
++)
1295 GenModList_insertMod(&gzone
, mod
);
1301 for(;zone
!= zone_end
;zone
++)
1303 GenModList lzone
= GenModList_clone(&gzone
);
1305 mod
= sfont
.pmod
+ zone
->mModIdx
;
1306 mod_end
= sfont
.pmod
+ (zone
+1)->mModIdx
;
1307 for(;mod
!= mod_end
;mod
++)
1308 GenModList_insertMod(&lzone
, mod
);
1310 gen
= sfont
.pgen
+ zone
->mGenIdx
;
1311 gen_end
= sfont
.pgen
+ (zone
+1)->mGenIdx
;
1312 for(;gen
!= gen_end
;gen
++)
1314 if(gen
->mGenerator
== 41)
1316 if(gen
->mAmount
>= sfont
.inst_size
-1)
1317 ERR("Generator %ld has invalid instrument ID (%d of %d)\n",
1318 (long)(gen
-sfont
.pgen
), gen
->mAmount
, sfont
.inst_size
-1);
1320 processInstrument(&sounds
, &sounds_size
, context
,
1321 &sfont
.inst
[gen
->mAmount
], &sfont
.phdr
[i
], &sfont
, &lzone
);
1324 GenModList_insertGen(&lzone
, gen
, AL_TRUE
);
1326 GenModList_Destruct(&lzone
);
1333 presets
[presets_size
] = NewPreset(context
);
1334 presets
[presets_size
]->Preset
= sfont
.phdr
[i
].mPreset
;
1335 presets
[presets_size
]->Bank
= sfont
.phdr
[i
].mBank
;
1337 for(j
= 0;j
< sounds_size
;j
++)
1338 IncrementRef(&sounds
[j
]->ref
);
1339 sounds
= ExchangePtr((XchgPtr
*)&presets
[presets_size
]->Sounds
, sounds
);
1340 ExchangeInt(&presets
[presets_size
]->NumSounds
, sounds_size
);
1345 GenModList_Destruct(&gzone
);
1348 for(i
= 0;i
< presets_size
;i
++)
1349 IncrementRef(&presets
[i
]->ref
);
1350 presets
= ExchangePtr((XchgPtr
*)&soundfont
->Presets
, presets
);
1351 ExchangeInt(&soundfont
->NumPresets
, presets_size
);
1355 Soundfont_Destruct(&sfont
);
1362 ALCdevice
*device
= context
->Device
;
1363 for(i
= 0;i
< presets_size
;i
++)
1364 DeletePreset(presets
[i
], device
);
1368 Soundfont_Destruct(&sfont
);