Don't break with an override root key generator value of -1
[openal-soft.git] / Alc / midi / sf2load.c
blob7f979f833250f7c8bb024c6bdd1cf01a22082633
2 #include "config.h"
4 #include <stdio.h>
5 #include <stdlib.h>
7 #include "alMain.h"
8 #include "alMidi.h"
9 #include "alError.h"
10 #include "alu.h"
12 #include "midi/base.h"
15 static ALuint read_le32(Reader *stream)
17 ALubyte buf[4];
18 if(READ(stream, buf, 4) != 4)
20 READERR(stream) = 1;
21 return 0;
23 return (buf[3]<<24) | (buf[2]<<16) | (buf[1]<<8) | buf[0];
25 static ALushort read_le16(Reader *stream)
27 ALubyte buf[2];
28 if(READ(stream, buf, 2) != 2)
30 READERR(stream) = 1;
31 return 0;
33 return (buf[1]<<8) | buf[0];
35 static ALubyte read_8(Reader *stream)
37 ALubyte buf[1];
38 if(READ(stream, buf, 1) != 1)
40 READERR(stream) = 1;
41 return 0;
43 return buf[0];
45 static void skip(Reader *stream, ALuint amt)
47 while(amt > 0 && !READERR(stream))
49 char buf[4096];
50 size_t got;
52 got = READ(stream, buf, minu(sizeof(buf), amt));
53 if(got == 0) READERR(stream) = 1;
55 amt -= got;
59 typedef struct Generator {
60 ALushort mGenerator;
61 ALushort mAmount;
62 } 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 */
84 0, /* 14 - */
85 0, /* 15 - chorusEffectsSend */
86 0, /* 16 - reverbEffectsSend */
87 0, /* 17 - pan */
88 0, /* 18 - */
89 0, /* 19 - */
90 0, /* 20 - */
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 */
111 0, /* 41 - */
112 0, /* 42 - */
113 0, /* 43 - keyRange */
114 0, /* 44 - velRange */
115 0, /* 45 - startloopAddrCoarseOffset */
116 0, /* 46 - keynum */
117 0, /* 47 - velocity */
118 0, /* 48 - initialAttenuation */
119 0, /* 49 - */
120 0, /* 50 - endloopAddrCoarseOffset */
121 0, /* 51 - corseTune */
122 0, /* 52 - fineTune */
123 0, /* 53 - */
124 0, /* 54 - sampleModes */
125 0, /* 55 - */
126 100, /* 56 - scaleTuning */
127 0, /* 57 - exclusiveClass */
128 0, /* 58 - overridingRootKey */
129 0, /* 59 - */
132 typedef struct Modulator {
133 ALushort mSrcOp;
134 ALushort mDstOp;
135 ALshort mAmount;
136 ALushort mAmtSrcOp;
137 ALushort mTransOp;
138 } 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 {
149 ALushort mGenIdx;
150 ALushort mModIdx;
151 } 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 {
159 ALchar mName[20];
160 ALushort mPreset; /* MIDI program number */
161 ALushort mBank;
162 ALushort mZoneIdx;
163 ALuint mLibrary;
164 ALuint mGenre;
165 ALuint mMorphology;
166 } PresetHeader;
167 static void PresetHeader_read(PresetHeader *self, Reader *stream)
169 if(READ(stream, self->mName, sizeof(self->mName)) != sizeof(self->mName))
170 READERR(stream) = 1;
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 {
180 ALchar mName[20];
181 ALushort mZoneIdx;
182 } InstrumentHeader;
183 static void InstrumentHeader_read(InstrumentHeader *self, Reader *stream)
185 if(READ(stream, self->mName, sizeof(self->mName)) != sizeof(self->mName))
186 READERR(stream) = 1;
187 self->mZoneIdx = read_le16(stream);
190 typedef struct SampleHeader {
191 ALchar mName[20]; // 20 bytes
192 ALuint mStart;
193 ALuint mEnd;
194 ALuint mStartloop;
195 ALuint mEndloop;
196 ALuint mSampleRate;
197 ALubyte mOriginalKey;
198 ALbyte mCorrection;
199 ALushort mSampleLink;
200 ALushort mSampleType;
201 } SampleHeader;
202 static void SampleHeader_read(SampleHeader *self, Reader *stream)
204 if(READ(stream, self->mName, sizeof(self->mName)) != sizeof(self->mName))
205 READERR(stream) = 1;
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 {
219 PresetHeader *phdr;
220 ALsizei phdr_size;
222 Zone *pbag;
223 ALsizei pbag_size;
224 Modulator *pmod;
225 ALsizei pmod_size;
226 Generator *pgen;
227 ALsizei pgen_size;
229 InstrumentHeader *inst;
230 ALsizei inst_size;
232 Zone *ibag;
233 ALsizei ibag_size;
234 Modulator *imod;
235 ALsizei imod_size;
236 Generator *igen;
237 ALsizei igen_size;
239 SampleHeader *shdr;
240 ALsizei shdr_size;
241 } Soundfont;
243 static void Soundfont_Construct(Soundfont *self)
245 self->phdr = NULL;
246 self->phdr_size = 0;
248 self->pbag = NULL;
249 self->pbag_size = 0;
250 self->pmod = NULL;
251 self->pmod_size = 0;
252 self->pgen = NULL;
253 self->pgen_size = 0;
255 self->inst = NULL;
256 self->inst_size = 0;
258 self->ibag = NULL;
259 self->ibag_size = 0;
260 self->imod = NULL;
261 self->imod_size = 0;
262 self->igen = NULL;
263 self->igen_size = 0;
265 self->shdr = NULL;
266 self->shdr_size = 0;
269 static void Soundfont_Destruct(Soundfont *self)
271 free(self->phdr);
272 self->phdr = NULL;
273 self->phdr_size = 0;
275 free(self->pbag);
276 self->pbag = NULL;
277 self->pbag_size = 0;
278 free(self->pmod);
279 self->pmod = NULL;
280 self->pmod_size = 0;
281 free(self->pgen);
282 self->pgen = NULL;
283 self->pgen_size = 0;
285 free(self->inst);
286 self->inst = NULL;
287 self->inst_size = 0;
289 free(self->ibag);
290 self->ibag = NULL;
291 self->ibag_size = 0;
292 free(self->imod);
293 self->imod = NULL;
294 self->imod_size = 0;
295 free(self->igen);
296 self->igen = NULL;
297 self->igen_size = 0;
299 free(self->shdr);
300 self->shdr = NULL;
301 self->shdr_size = 0;
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 {
308 ALuint mCode;
309 ALuint mSize;
310 } 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 {
319 Generator *gens;
320 ALsizei gens_size;
321 ALsizei gens_max;
323 Modulator *mods;
324 ALsizei mods_size;
325 ALsizei mods_max;
326 } GenModList;
328 static void GenModList_Construct(GenModList *self)
330 self->gens = NULL;
331 self->gens_size = 0;
332 self->gens_max = 0;
334 self->mods = NULL;
335 self->mods_size = 0;
336 self->mods_max = 0;
339 static void GenModList_Destruct(GenModList *self)
341 free(self->gens);
342 self->gens = NULL;
343 self->gens_size = 0;
344 self->gens_max = 0;
346 free(self->mods);
347 self->mods = NULL;
348 self->mods_size = 0;
349 self->mods_max = 0;
352 static GenModList GenModList_clone(const GenModList *self)
354 GenModList ret;
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;
366 return ret;
369 static void GenModList_insertGen(GenModList *self, const Generator *gen, ALboolean ispreset)
371 Generator *i = self->gens;
372 Generator *end = i + self->gens_size;
373 for(;i != end;i++)
375 if(i->mGenerator == gen->mGenerator)
377 i->mAmount = gen->mAmount;
378 return;
382 if(ispreset &&
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))
388 return;
390 if(self->gens_size == self->gens_max)
392 void *temp = NULL;
393 ALsizei newsize;
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]));
398 if(!temp)
400 ERR("Failed to increase generator storage to %d elements (from %d)\n",
401 newsize, self->gens_max);
402 return;
405 self->gens = temp;
406 self->gens_max = newsize;
409 self->gens[self->gens_size] = *gen;
410 self->gens_size++;
412 static void GenModList_accumGen(GenModList *self, const Generator *gen)
414 Generator *i = self->gens;
415 Generator *end = i + self->gens_size;
416 for(;i != end;i++)
418 if(i->mGenerator == gen->mGenerator)
420 if(gen->mGenerator == 43 || gen->mGenerator == 44)
422 /* Range generators accumulate by taking the intersection of
423 * the two ranges.
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;
429 else
430 i->mAmount += gen->mAmount;
431 return;
435 if(self->gens_size == self->gens_max)
437 void *temp = NULL;
438 ALsizei newsize;
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]));
443 if(!temp)
445 ERR("Failed to increase generator storage to %d elements (from %d)\n",
446 newsize, self->gens_max);
447 return;
450 self->gens = temp;
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];
457 self->gens_size++;
460 static void GenModList_insertMod(GenModList *self, const Modulator *mod)
462 Modulator *i = self->mods;
463 Modulator *end = i + self->mods_size;
464 for(;i != end;i++)
466 if(i->mDstOp == mod->mDstOp && i->mSrcOp == mod->mSrcOp &&
467 i->mAmtSrcOp == mod->mAmtSrcOp && i->mTransOp == mod->mTransOp)
469 i->mAmount = mod->mAmount;
470 return;
474 if(self->mods_size == self->mods_max)
476 void *temp = NULL;
477 ALsizei newsize;
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]));
482 if(!temp)
484 ERR("Failed to increase modulator storage to %d elements (from %d)\n",
485 newsize, self->mods_max);
486 return;
489 self->mods = temp;
490 self->mods_max = newsize;
493 self->mods[self->mods_size] = *mod;
494 self->mods_size++;
496 static void GenModList_accumMod(GenModList *self, const Modulator *mod)
498 Modulator *i = self->mods;
499 Modulator *end = i + self->mods_size;
500 for(;i != end;i++)
502 if(i->mDstOp == mod->mDstOp && i->mSrcOp == mod->mSrcOp &&
503 i->mAmtSrcOp == mod->mAmtSrcOp && i->mTransOp == mod->mTransOp)
505 i->mAmount += mod->mAmount;
506 return;
510 if(self->mods_size == self->mods_max)
512 void *temp = NULL;
513 ALsizei newsize;
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]));
518 if(!temp)
520 ERR("Failed to increase modulator storage to %d elements (from %d)\n",
521 newsize, self->mods_max);
522 return;
525 self->mods = temp;
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;*/
550 self->mods_size++;
554 #define ERROR_GOTO(lbl_, ...) do { \
555 ERR(__VA_ARGS__); \
556 goto lbl_; \
557 } while(0)
559 static ALboolean ensureFontSanity(const Soundfont *sfont)
561 ALsizei i;
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);
569 return AL_FALSE;
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);
575 return AL_FALSE;
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);
582 return AL_FALSE;
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);
591 return AL_FALSE;
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);
597 return AL_FALSE;
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);
603 return AL_FALSE;
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);
609 return AL_FALSE;
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);
616 return AL_FALSE;
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);
622 return AL_FALSE;
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);
632 return AL_FALSE;
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);
638 return AL_FALSE;
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);
645 return AL_FALSE;
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);
654 return AL_FALSE;
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);
660 return AL_FALSE;
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);
666 return AL_FALSE;
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);
672 return AL_FALSE;
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);
679 return AL_FALSE;
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);
685 return AL_FALSE;
688 return AL_TRUE;
691 static ALboolean checkZone(const GenModList *zone, const PresetHeader *preset, const InstrumentHeader *inst, const SampleHeader *samp)
693 ALsizei i;
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)",
708 low, high);
709 return AL_FALSE;
714 return AL_TRUE;
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;
726 if((type&0x80))
728 type ^= 0x80;
729 if(type > 0 && type < 120 && !(type == 6 || (type >= 32 && type <= 63) ||
730 (type >= 98 && type <= 101)))
731 return type;
732 type ^= 0x80;
734 ERR("Unhandled modulator source input: 0x%02x\n", type);
735 return AL_NONE;
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 */
755 0, /* 14 - */
756 AL_CHORUS_SEND_SOFT, /* 15 - chorusEffectsSend */
757 AL_REVERB_SEND_SOFT, /* 16 - reverbEffectsSend */
758 AL_PAN_SOFT, /* 17 - pan */
759 0, /* 18 - */
760 0, /* 19 - */
761 0, /* 20 - */
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 */
782 0, /* 41 - */
783 0, /* 42 - */
784 AL_KEY_RANGE_SOFT, /* 43 - keyRange */
785 AL_VELOCITY_RANGE_SOFT, /* 44 - velRange */
786 0, /* 45 - startloopAddrCoarseOffset */
787 0, /* 46 - keynum */
788 0, /* 47 - velocity */
789 AL_ATTENUATION_SOFT, /* 48 - initialAttenuation */
790 0, /* 49 - */
791 0, /* 50 - endloopAddrCoarseOffset */
792 AL_TUNING_COARSE_SOFT, /* 51 - corseTune */
793 AL_TUNING_FINE_SOFT, /* 52 - fineTune */
794 0, /* 53 - */
795 AL_LOOP_MODE_SOFT, /* 54 - sampleModes */
796 0, /* 55 - */
797 AL_TUNING_SCALE_SOFT, /* 56 - scaleTuning */
798 AL_EXCLUSIVE_CLASS_SOFT, /* 57 - exclusiveClass */
799 AL_BASE_KEY_SOFT, /* 58 - overridingRootKey */
800 0, /* 59 - */
802 const Generator *gen, *gen_end;
804 if(zone->mods)
806 ALsizei i;
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;
815 if(!dst)
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);
839 gen = zone->gens;
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)
847 sound->End += value;
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);
870 else
872 ALenum param = 0;
873 if(gen->mGenerator < 60)
874 param = Gen2Param[gen->mGenerator];
875 if(param)
877 if(param == AL_BASE_KEY_SOFT && value == -1)
878 continue;
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))
886 value = 0;
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;
908 GenModList gzone;
909 ALvoid *temp;
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)
926 break;
929 if(gen == gen_end)
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);
941 zone++;
945 temp = realloc(*sounds, (zone_end-zone + *sounds_size)*sizeof((*sounds)[0]));
946 if(!temp)
948 ERR("Failed reallocating fontsound storage to %ld elements (from %d)\n",
949 (zone_end-zone + *sounds_size), *sounds_size);
950 return;
952 *sounds = temp;
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);
973 break;
975 samp = &sfont->shdr[gen->mAmount];
977 gen = pzone->gens;
978 gen_end = gen + pzone->gens_size;
979 for(;gen != gen_end;gen++)
980 GenModList_accumGen(&lzone, gen);
982 mod = pzone->mods;
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))
988 break;
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);
1000 (*sounds_size)++;
1002 break;
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;
1017 ALuint version = 0;
1018 ALuint ltype;
1019 Soundfont sfont;
1020 RiffHdr riff;
1021 RiffHdr list;
1022 ALsizei i;
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));
1040 list.mSize -= 4;
1041 while(list.mSize > 0 && !READERR(stream))
1043 RiffHdr info;
1045 RiffHdr_read(&info, stream);
1046 list.mSize -= 8;
1047 if(info.mCode == FOURCC('i','f','i','l'))
1049 if(info.mSize != 4)
1050 ERR("Invalid ifil chunk size: %d\n", info.mSize);
1051 else
1053 ALushort major = read_le16(stream);
1054 ALushort minor = read_le16(stream);
1056 info.mSize -= 4;
1057 list.mSize -= 4;
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));
1077 list.mSize -= 4;
1079 ALbyte *ptr;
1080 RiffHdr smpl;
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));
1085 list.mSize -= 8;
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);
1097 else
1099 while(smpl.mSize > 0)
1101 ALbyte buf[4096];
1102 ALuint todo = minu(smpl.mSize, sizeof(buf));
1103 ALuint i;
1105 READ(stream, buf, todo);
1106 for(i = 0;i < todo;i++)
1107 ptr[i] = buf[i^1];
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))
1221 goto error;
1223 presets = calloc(1, (sfont.phdr_size-1)*sizeof(presets[0]));
1224 if(!presets)
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;
1234 GenModList gzone;
1236 if(sfont.phdr[i+1].mZoneIdx == sfont.phdr[i].mZoneIdx)
1237 continue;
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)
1251 break;
1254 if(gen == gen_end)
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);
1266 zone++;
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);
1288 else
1289 processInstrument(&sounds, &sounds_size, context,
1290 &sfont.inst[gen->mAmount], &sfont.phdr[i], &sfont, &lzone);
1291 break;
1293 GenModList_insertGen(&lzone, gen, AL_TRUE);
1295 GenModList_Destruct(&lzone);
1298 if(sounds_size > 0)
1300 ALsizei j;
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);
1310 presets_size++;
1312 free(sounds);
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);
1322 free(presets);
1324 Soundfont_Destruct(&sfont);
1326 return AL_TRUE;
1328 error:
1329 if(presets)
1331 ALCdevice *device = context->Device;
1332 for(i = 0;i < presets_size;i++)
1333 DeletePreset(presets[i], device);
1334 free(presets);
1337 Soundfont_Destruct(&sfont);
1339 return AL_FALSE;