1 #include <stdio.h>
2 #include <string.h>
3 #include <errno.h>
4 #include <math.h>
5 
6 #include "doomdef.h"
7 #include "m_swap.h"
8 #include "templates.h"
9 #include "timidity.h"
10 #include "sf2.h"
11 #include "files.h"
12 
13 using namespace Timidity;
14 
15 #define cindex(identifier)	(BYTE)(((size_t)&((SFGenComposite *)1)->identifier - 1) / 2)
16 
17 class CIOErr {};
18 class CBadForm {};
19 class CBadVer {};
20 
21 struct ListHandler
22 {
23 	DWORD ID;
24 	void (*Parser)(SFFile *sf2, FileReader *f, DWORD chunkid, DWORD chunklen);
25 };
26 
27 enum
28 {
29 	GENF_InstrOnly	= 1,	// Only valid at intstrument level
30 	GENF_PresetOnly	= 2,	// Only valid at preset level
31 	GENF_Range		= 4,	// Value is a range,
32 	GENF_Index		= 8,	// Value is an index (aka unsigned)
33 	GENF_32768_Ok	= 16,	// -32768 is a valid value
34 };
35 struct GenDef
36 {
37 	short Min;
38 	short Max;
39 	BYTE StructIndex;
40 	BYTE Flags;
41 };
42 
43 static const GenDef GenDefs[] =
44 {
45 	/*  0 */ {		  0,	32767, cindex(startAddrsOffset),			GENF_InstrOnly },
46 	/*  1 */ {   -32768,		0, cindex(endAddrsOffset),				GENF_InstrOnly },
47 	/*  2 */ {   -32768,	32767, cindex(startLoopAddrsOffset),		GENF_InstrOnly },
48 	/*  3 */ {   -32768,	32767, cindex(endLoopAddrsOffset),			GENF_InstrOnly },
49 	/*  4 */ {		  0,	32767, cindex(startAddrsCoarseOffset),		GENF_InstrOnly },
50 	/*  5 */ {   -12000,	12000, cindex(modLfoToPitch),				0 },
51 	/*  6 */ {   -12000,	12000, cindex(vibLfoToPitch),				0 },
52 	/*  7 */ {   -12000,	12000, cindex(modEnvToPitch),				0 },
53 	/*  8 */ {	   1500,	13500, cindex(initialFilterFc),				0 },
54 	/*  9 */ {		  0,	  960, cindex(initialFilterQ),				0 },
55 	/* 10 */ {   -12000,	12000, cindex(modLfoToFilterFc),			0 },
56 	/* 11 */ {   -12000,	12000, cindex(modEnvToFilterFc),			0 },
57 	/* 12 */ {   -32768,		0, cindex(endAddrsCoarseOffset),		0 },
58 	/* 13 */ {	   -960,	  960, cindex(modLfoToVolume),				0 },
59 	/* 14 */ {		  0,		0, 255 /* unused1 */,					0 },
60 	/* 15 */ {		  0,	 1000, cindex(chorusEffectsSend),			0 },
61 	/* 16 */ {		  0,	 1000, cindex(reverbEffectsSend),			0 },
62 	/* 17 */ {	   -500,	  500, cindex(pan),							0 },
63 	/* 18 */ {		  0,		0, 255 /* unused2 */,					0 },
64 	/* 19 */ {		  0,		0, 255 /* unused3 */,					0 },
65 	/* 20 */ {		  0,		0, 255 /* unused4 */,					0 },
66 	/* 21 */ {   -12000,	 5000, cindex(delayModLFO),					GENF_32768_Ok },
67 	/* 22 */ {   -16000,	 4500, cindex(freqModLFO),					0 },
68 	/* 23 */ {   -12000,	 5000, cindex(delayVibLFO),					GENF_32768_Ok },
69 	/* 24 */ {   -16000,	 4500, cindex(freqVibLFO),					0 },
70 	/* 25 */ {   -12000,	 5000, cindex(delayModEnv),					GENF_32768_Ok },
71 	/* 26 */ {   -12000,	 8000, cindex(attackModEnv),				GENF_32768_Ok },
72 	/* 27 */ {   -12000,	 5000, cindex(holdModEnv),					GENF_32768_Ok },
73 	/* 28 */ {   -12000,	 8000, cindex(decayModEnv),					0 },
74 	/* 29 */ {		  0,	 1000, cindex(sustainModEnv),				0 },
75 	/* 30 */ {   -12000,	 8000, cindex(releaseModEnv),				0 },
76 	/* 31 */ {	  -1200,	 1200, cindex(keynumToModEnvHold),			0 },
77 	/* 32 */ {	  -1200,	 1200, cindex(keynumToModEnvDecay),			0 },
78 	/* 33 */ {   -12000,	 5000, cindex(delayVolEnv),					GENF_32768_Ok },
79 	/* 34 */ {   -12000,	 8000, cindex(attackVolEnv),				GENF_32768_Ok },
80 	/* 35 */ {   -12000,	 5000, cindex(holdVolEnv),					GENF_32768_Ok },
81 	/* 36 */ {   -12000,	 5000, cindex(decayVolEnv),					0 },
82 	/* 37 */ {		  0,	 1440, cindex(sustainVolEnv),				0 },
83 	/* 38 */ {   -12000,	 8000, cindex(releaseVolEnv),				0 },
84 	/* 39 */ {	  -1200,	 1200, cindex(keynumToVolEnvHold),			0 },
85 	/* 40 */ {	  -1200,	 1200, cindex(keynumToVolEnvDecay),			0 },
86 	/* 41 */ {   -32768,	32767, 255 /* instrument */,				GENF_Index | GENF_PresetOnly },
87 	/* 42 */ {		  0,		0, 255 /* reserved1 */,					0 },
88 	/* 43 */ {		  0,	  127, 255 /* keyRange */,					GENF_Range },
89 	/* 44 */ {		  0,	  127, 255 /* velRange */,					GENF_Range },
90 	/* 45 */ {   -32768,	32767, cindex(startLoopAddrsCoarseOffset),	GENF_InstrOnly },
91 	/* 46 */ {		  0,	  127, cindex(keynum),						GENF_InstrOnly },
92 	/* 47 */ {		  1,	  127, cindex(velocity),					GENF_InstrOnly },
93 	/* 48 */ {		  0,	 1440, cindex(initialAttenuation),			0 },
94 	/* 49 */ {		  0,		0, 255 /* reserved2 */,					0 },
95 	/* 50 */ {   -32768,  32767, cindex(endLoopAddrsCoarseOffset),	GENF_InstrOnly },
96 	/* 51 */ {	   -120,	  120, cindex(coarseTune),					0 },
97 	/* 52 */ {	    -99,	   99, cindex(fineTune),					0 },
98 	/* 53 */ {   -32768,	32767, 255 /* sampleID */,					GENF_Index | GENF_InstrOnly },
99 	/* 54 */ {   -32768,	32767, cindex(sampleModes),					GENF_InstrOnly },
100 	/* 55 */ {		  0,		0, 255 /* reserved3 */,					0 },
101 	/* 56 */ {		  0,	 1200, cindex(scaleTuning),					0 },
102 	/* 57 */ {		  1,	  127, cindex(exclusiveClass),				GENF_InstrOnly },
103 	/* 58 */ {		  0,	  127, cindex(overridingRootKey),			GENF_InstrOnly },
104 };
105 
106 static const SFGenComposite DefaultGenerators =
107 {
108 	{ { 0, 127 } },	// keyRange
109 	{ 0, 127 },		// velRange
110 	{ 0 },			// instrument/sampleID
111 	0,				// modLfoToPitch
112 	0,				// vibLfoToPitch
113 	0,				// modEnvToPitch
114 	13500,			// initialFilterFc
115 	0,				// initialFilterQ
116 	0,				// modLfoToFilterFc
117 	0,				// modEnvToFilterFc
118 	0,				// modLfoToVolume
119 	0,				// chorusEffectsSend
120 	0,				// reverbEffectsSend
121 	0,				// pan
122 	-12000,			// delayModLFO
123 	0,				// freqModLFO
124 	-12000,			// delayVibLFO
125 	0,				// freqVibLFO
126 	-12000,			// delayModEnv
127 	-12000,			// attackModEnv
128 	-12000,			// holdModEnv
129 	-12000,			// decayModEnv
130 	0,				// sustainModEnv
131 	-12000,			// releaseModEnv
132 	0,				// keynumToModEnvHold
133 	0,				// keynumToModEnvDecay
134 	-12000,			// delayVolEnv
135 	-12000,			// attackVolEnv
136 	-12000,			// holdVolEnv
137 	-12000,			// decayVolEnv
138 	0,				// sustainVolEnv
139 	-12000,			// releaseVolEnv
140 	0,				// keynumToVolEnvHold
141 	0,				// keynumToVolEnvDecay
142 	0,				// initialAttenuation
143 	0,				// coarseTune
144 	0,				// fineTune
145 	100,			// scaleTuning
146 
147 	0, 0,			// startAddrs(Coarse)Offset
148 	0, 0,			// endAddrs(Coarse)Offset
149 	0, 0,			// startLoop(Coarse)Offset
150 	0, 0,			// endLoop(Coarse)Offset
151 	-1,				// keynum
152 	-1,				// velocity
153 	0,				// sampleModes
154 	0,				// exclusiveClass
155 	-1				// overridingRootKey
156 };
157 
158 static void ParseIfil(SFFile *sf2, FileReader *f, DWORD chunkid, DWORD chunklen);
159 static void ParseSmpl(SFFile *sf2, FileReader *f, DWORD chunkid, DWORD chunklen);
160 static void ParseSm24(SFFile *sf2, FileReader *f, DWORD chunkid, DWORD chunklen);
161 static void ParsePhdr(SFFile *sf2, FileReader *f, DWORD chunkid, DWORD chunklen);
162 static void ParseBag(SFFile *sf2, FileReader *f, DWORD chunkid, DWORD chunklen);
163 static void ParseMod(SFFile *sf2, FileReader *f, DWORD chunkid, DWORD chunklen);
164 static void ParseGen(SFFile *sf2, FileReader *f, DWORD chunkid, DWORD chunklen);
165 static void ParseInst(SFFile *sf2, FileReader *f, DWORD chunkid, DWORD chunklen);
166 static void ParseShdr(SFFile *sf2, FileReader *f, DWORD chunkid, DWORD chunklen);
167 
168 ListHandler INFOHandlers[] =
169 {
170 	{ ID_ifil, ParseIfil },
171 	{ 0, 0 }
172 };
173 
174 ListHandler SdtaHandlers[] =
175 {
176 	{ ID_smpl, ParseSmpl },
177 	{ ID_sm24, ParseSm24 },
178 	{ 0, 0 }
179 };
180 
181 ListHandler PdtaHandlers[] =
182 {
183 	{ ID_phdr, ParsePhdr },
184 	{ ID_pbag, ParseBag },
185 	{ ID_pmod, ParseMod },
186 	{ ID_pgen, ParseGen },
187 	{ ID_inst, ParseInst },
188 	{ ID_ibag, ParseBag },
189 	{ ID_imod, ParseMod },
190 	{ ID_igen, ParseGen },
191 	{ ID_shdr, ParseShdr },
192 	{ 0, 0 }
193 };
194 
timecent_to_sec(SWORD timecent)195 static double timecent_to_sec(SWORD timecent)
196 {
197 	if (timecent == -32768)
198 		return 0;
199 	return pow(2.0, timecent / 1200.0);
200 }
201 
to_offset(int offset)202 static SDWORD to_offset(int offset)
203 {
204 	return (SDWORD)offset << (7+15);
205 }
206 
calc_rate(Renderer * song,int diff,double sec)207 static SDWORD calc_rate(Renderer *song, int diff, double sec)
208 {
209 	double rate;
210 
211 	if(sec < 0.006)
212 		sec = 0.006;
213 	if(diff == 0)
214 		diff = 255;
215 	diff <<= (7+15);
216 	rate = ((double)diff / song->rate) * song->control_ratio / sec;
217 	return (SDWORD)rate;
218 }
219 
220 
read_id(FileReader * f)221 static inline DWORD read_id(FileReader *f)
222 {
223 	DWORD id;
224 	if (f->Read(&id, 4) != 4)
225 	{
226 		throw CIOErr();
227 	}
228 	return id;
229 }
230 
read_byte(FileReader * f)231 static inline int read_byte(FileReader *f)
232 {
233 	BYTE x;
234 	if (f->Read(&x, 1) != 1)
235 	{
236 		throw CIOErr();
237 	}
238 	return x;
239 }
240 
read_char(FileReader * f)241 static inline int read_char(FileReader *f)
242 {
243 	SBYTE x;
244 	if (f->Read(&x, 1) != 1)
245 	{
246 		throw CIOErr();
247 	}
248 	return x;
249 }
250 
read_uword(FileReader * f)251 static inline int read_uword(FileReader *f)
252 {
253 	WORD x;
254 	if (f->Read(&x, 2) != 2)
255 	{
256 		throw CIOErr();
257 	}
258 	return LittleShort(x);
259 }
260 
read_sword(FileReader * f)261 static inline int read_sword(FileReader *f)
262 {
263 	SWORD x;
264 	if (f->Read(&x, 2) != 2)
265 	{
266 		throw CIOErr();
267 	}
268 	return LittleShort(x);
269 }
270 
read_dword(FileReader * f)271 static inline DWORD read_dword(FileReader *f)
272 {
273 	DWORD x;
274 	if (f->Read(&x, 4) != 4)
275 	{
276 		throw CIOErr();
277 	}
278 	return LittleLong(x);
279 }
280 
read_name(FileReader * f,char name[21])281 static inline void read_name(FileReader *f, char name[21])
282 {
283 	if (f->Read(name, 20) != 20)
284 	{
285 		throw CIOErr();
286 	}
287 	name[20] = 0;
288 }
289 
skip_chunk(FileReader * f,DWORD len)290 static inline void skip_chunk(FileReader *f, DWORD len)
291 {
292 	// RIFF, like IFF, adds an extra pad byte to the end of
293 	// odd-sized chunks so that new chunks are always on even
294 	// byte boundaries.
295 	if (f->Seek(len + (len & 1), SEEK_CUR) != 0)
296 	{
297 		throw CIOErr();
298 	}
299 }
300 
check_list(FileReader * f,DWORD id,DWORD filelen,DWORD & chunklen)301 static void check_list(FileReader *f, DWORD id, DWORD filelen, DWORD &chunklen)
302 {
303 	if (read_id(f) != ID_LIST)
304 	{
305 		throw CBadForm();
306 	}
307 	chunklen = read_dword(f);
308 	if (chunklen + 8 > filelen)
309 	{
310 		throw CBadForm();
311 	}
312 	if (read_id(f) != id)
313 	{
314 		throw CBadForm();
315 	}
316 }
317 
ParseIfil(SFFile * sf2,FileReader * f,DWORD chunkid,DWORD chunklen)318 static void ParseIfil(SFFile *sf2, FileReader *f, DWORD chunkid, DWORD chunklen)
319 {
320 	WORD major, minor;
321 
322 	if (chunklen != 4)
323 	{
324 		throw CBadForm();
325 	}
326 
327 	major = read_uword(f);
328 	minor = read_uword(f);
329 
330 	if (major != 2)
331 	{
332 		throw CBadVer();
333 	}
334 	sf2->MinorVersion = minor;
335 }
336 
ParseLIST(SFFile * sf2,FileReader * f,DWORD chunklen,ListHandler * handlers)337 static void ParseLIST(SFFile *sf2, FileReader *f, DWORD chunklen, ListHandler *handlers)
338 {
339 	ListHandler *handler;
340 	DWORD id;
341 	DWORD len;
342 
343 	chunklen -= 4;
344 	while (chunklen > 0)
345 	{
346 		id = read_id(f);
347 		len = read_dword(f);
348 
349 		if (len + 8 > chunklen)
350 		{
351 			throw CBadForm();
352 		}
353 		chunklen -= len + (len & 1) + 8;
354 
355 		for (handler = handlers; handler->ID != 0; ++handler)
356 		{
357 			if (handler->ID == id && handler->Parser != NULL)
358 			{
359 				handler->Parser(sf2, f, id, len);
360 				break;
361 			}
362 		}
363 		if (handler->ID == 0)
364 		{
365 			// Skip unknown chunks
366 			skip_chunk(f, len);
367 		}
368 	}
369 }
370 
ParseINFO(SFFile * sf2,FileReader * f,DWORD chunklen)371 static void ParseINFO(SFFile *sf2, FileReader *f, DWORD chunklen)
372 {
373 	sf2->MinorVersion = -1;
374 
375 	ParseLIST(sf2, f, chunklen, INFOHandlers);
376 
377 	if (sf2->MinorVersion < 0)
378 	{ // The ifil chunk must be present.
379 		throw CBadForm();
380 	}
381 }
382 
ParseSdta(SFFile * sf2,FileReader * f,DWORD chunklen)383 static void ParseSdta(SFFile *sf2, FileReader *f, DWORD chunklen)
384 {
385 	ParseLIST(sf2, f, chunklen, SdtaHandlers);
386 	if (sf2->SampleDataOffset == 0)
387 	{
388 		throw CBadForm();
389 	}
390 	// Section 6.2, page 20: It is not clear if the extra pad byte for an
391 	// odd chunk is supposed to be included in the chunk length field.
392 	if (sf2->SizeSampleDataLSB != sf2->SizeSampleData &&
393 		sf2->SizeSampleDataLSB != sf2->SizeSampleData + (sf2->SizeSampleData & 1))
394 	{
395 		sf2->SampleDataLSBOffset = 0;
396 		sf2->SizeSampleDataLSB = 0;
397 	}
398 }
399 
ParseSmpl(SFFile * sf2,FileReader * f,DWORD chunkid,DWORD chunklen)400 static void ParseSmpl(SFFile *sf2, FileReader *f, DWORD chunkid, DWORD chunklen)
401 {
402 	// Only use the first smpl chunk. (Or should we reject files with more than one?)
403 	if (sf2->SampleDataOffset == 0)
404 	{
405 		if (chunklen & 1)
406 		{ // Chunk must be an even number of bytes.
407 			throw CBadForm();
408 		}
409 		sf2->SampleDataOffset = f->Tell();
410 		sf2->SizeSampleData = chunklen >> 1;
411 	}
412 	skip_chunk(f, chunklen);
413 }
414 
ParseSm24(SFFile * sf2,FileReader * f,DWORD chunkid,DWORD chunklen)415 static void ParseSm24(SFFile *sf2, FileReader *f, DWORD chunkid, DWORD chunklen)
416 {
417 	// The sm24 chunk is ignored if the file version is < 2.04
418 	if (sf2->MinorVersion >= 4)
419 	{
420 		// Only use the first sm24 chunk. (Or should we reject files with more than one?)
421 		if (sf2->SampleDataLSBOffset == 0)
422 		{
423 			sf2->SampleDataLSBOffset = f->Tell();
424 			sf2->SizeSampleDataLSB = chunklen;
425 		}
426 	}
427 	skip_chunk(f, chunklen);
428 }
429 
ParsePdta(SFFile * sf2,FileReader * f,DWORD chunklen)430 static void ParsePdta(SFFile *sf2, FileReader *f, DWORD chunklen)
431 {
432 	ParseLIST(sf2, f, chunklen, PdtaHandlers);
433 }
434 
ParsePhdr(SFFile * sf2,FileReader * f,DWORD chunkid,DWORD chunklen)435 static void ParsePhdr(SFFile *sf2, FileReader *f, DWORD chunkid, DWORD chunklen)
436 {
437 	SFPreset *preset;
438 
439 	// Section 7.2, page 22:
440 	//		If the PHDR sub-chunk is missing, or contains fewer than two records,
441 	//		or its size is not a multiple of 38 bytes, the file should be rejected
442 	//		as structurally unsound.
443 	if (chunklen < 38*2 || chunklen % 38 != 0)
444 	{
445 		throw CBadForm();
446 	}
447 
448 	sf2->NumPresets = chunklen / 38;
449 	sf2->Presets = new SFPreset[sf2->NumPresets];
450 	preset = sf2->Presets;
451 
452 	for (int i = sf2->NumPresets; i != 0; --i, ++preset)
453 	{
454 		read_name(f, preset->Name);
455 		preset->Program = read_uword(f);
456 		preset->Bank = read_uword(f);
457 		preset->BagIndex = read_uword(f);
458 		skip_chunk(f, 4*3);	// Skip library, genre, and morphology
459 
460 		// Section 7.2, page 22:
461 		//		The preset bag indices will be monotonically increasing with
462 		//		increasing preset headers.
463 		if (preset != sf2->Presets)
464 		{
465 			if (preset->BagIndex < (preset - 1)->BagIndex)
466 			{
467 				throw CBadForm();
468 			}
469 		}
470 	}
471 }
472 
ParseBag(SFFile * sf2,FileReader * f,DWORD chunkid,DWORD chunklen)473 static void ParseBag(SFFile *sf2, FileReader *f, DWORD chunkid, DWORD chunklen)
474 {
475 	SFBag *bags, *bag;
476 	WORD prev_mod = 0;
477 	int numbags;
478 	int i;
479 
480 	// Section 7.3, page 22:
481 	//		It is always a multiple of four bytes in length, and contains one
482 	//		record for each preset zone plus one record for a terminal zone. ...
483 	//		If the PBAG sub-chunk is missing, or its size is not a multiple of
484 	//		four bytes, the file should be rejected as structurally unsound.
485 	// Section 7.7: IBAG is the same, but substitute "instrument" for "preset".
486 	if (chunklen & 3)
487 	{
488 		throw CBadForm();
489 	}
490 
491 	numbags = chunklen >> 2;
492 
493 	if (chunkid == ID_pbag)
494 	{
495 		if (numbags != sf2->Presets[sf2->NumPresets - 1].BagIndex + 1)
496 		{
497 			throw CBadForm();
498 		}
499 		sf2->PresetBags = bags = new SFBag[numbags];
500 		sf2->NumPresetBags = numbags;
501 	}
502 	else
503 	{
504 		assert(chunkid == ID_ibag);
505 		if (numbags != sf2->Instruments[sf2->NumInstruments - 1].BagIndex + 1)
506 		{
507 			throw CBadForm();
508 		}
509 		sf2->InstrBags = bags = new SFBag[numbags];
510 		sf2->NumInstrBags = numbags;
511 	}
512 
513 	for (bag = bags, i = numbags; i != 0; --i, ++bag)
514 	{
515 		bag->GenIndex = read_uword(f);
516 		WORD mod = read_uword(f);
517 		// Section 7.3, page 22:
518 		//		If the generator or modulator indices are non-monotonic or do not
519 		//		match the size of the respective PGEN or PMOD sub-chunks, the file
520 		//		is structurally defective and should be rejected at load time.
521 		if (bag != bags)
522 		{
523 			if (bag->GenIndex < (bag - 1)->GenIndex || mod < prev_mod)
524 			{
525 				throw CBadForm();
526 			}
527 		}
528 		prev_mod = mod;
529 		bag->KeyRange.Lo = bag->VelRange.Lo = 0;
530 		bag->KeyRange.Hi = bag->VelRange.Hi = 127;
531 		bag->Target = -1;
532 	}
533 }
534 
ParseMod(SFFile * sf2,FileReader * f,DWORD chunkid,DWORD chunklen)535 static void ParseMod(SFFile *sf2, FileReader *f, DWORD chunkid, DWORD chunklen)
536 {
537 	// Section 7.4, page 23:
538 	//		It [the PMOD sub-chunk] is always a multiple of ten bytes in length,
539 	//		and contains zero or more modulators plus a terminal record
540 	if (chunklen % 10 != 0)
541 	{
542 		throw CBadForm();
543 	}
544 	// We've checked the length, now ignore the chunk.
545 	skip_chunk(f, chunklen);
546 }
547 
ParseGen(SFFile * sf2,FileReader * f,DWORD chunkid,DWORD chunklen)548 static void ParseGen(SFFile *sf2, FileReader *f, DWORD chunkid, DWORD chunklen)
549 {
550 	SFGenList *gens, *gen;
551 	int numgens;
552 	int i;
553 
554 	// Section 7.5, page 24:
555 	//		If the PGEN sub-chunk is missing, or its size is not a multiple of
556 	//		four bytes, the file should be rejected as structurally unsound.
557 	if (chunklen & 3)
558 	{
559 		throw CBadForm();
560 	}
561 	numgens = chunklen >> 2;
562 
563 	if (chunkid == ID_pgen)
564 	{
565 		// Section 7.3, page 22:
566 		//		the size of the PGEN sub-chunk in bytes will be equal to four
567 		//		times the terminal preset�s wGenNdx plus four.
568 		if (numgens != sf2->PresetBags[sf2->NumPresetBags - 1].GenIndex + 1)
569 		{
570 			throw CBadForm();
571 		}
572 		sf2->PresetGenerators = gens = new SFGenList[numgens];
573 		sf2->NumPresetGenerators = numgens;
574 	}
575 	else
576 	{
577 		assert(chunkid == ID_igen);
578 		if (numgens != sf2->InstrBags[sf2->NumInstrBags - 1].GenIndex + 1)
579 		{
580 			throw CBadForm();
581 		}
582 		sf2->InstrGenerators = gens = new SFGenList[numgens];
583 		sf2->NumInstrGenerators = numgens;
584 	}
585 
586 	for (i = numgens, gen = gens; i != 0; --i, ++gen)
587 	{
588 		gen->Oper = read_uword(f);
589 		gen->uAmount = read_uword(f);
590 #ifdef __BIG_ENDIAN__
591 		if (gen->Oper == GEN_keyRange || gen->Oper == GEN_velRange)
592 		{
593 			// Reswap range generators
594 			gen->uAmount = LittleShort(gen->uAmount);
595 		}
596 #endif
597 	}
598 }
599 
ParseInst(SFFile * sf2,FileReader * f,DWORD chunkid,DWORD chunklen)600 static void ParseInst(SFFile *sf2, FileReader *f, DWORD chunkid, DWORD chunklen)
601 {
602 	int i;
603 	SFInst *inst;
604 
605 	// Section 7.6, page 25:
606 	//		If the INST sub-chunk is missing, contains fewer than two records, or its
607 	//		size is not a multiple of 22 bytes, the file should be rejected as
608 	//		structurally unsound.
609 	if (chunklen < 22*2 || chunklen % 22 != 0)
610 	{
611 		throw CBadForm();
612 	}
613 
614 	sf2->NumInstruments = chunklen / 22;
615 	sf2->Instruments = inst = new SFInst[sf2->NumInstruments];
616 	for (i = sf2->NumInstruments; i != 0; --i, ++inst)
617 	{
618 		read_name(f, inst->Name);
619 		inst->BagIndex = read_uword(f);
620 
621 		// Section 7.6, page 25:
622 		//		If the instrument bag indices are non-monotonic or if the terminal
623 		//		instrument�s wInstBagNdx does not match the IBAG sub-chunk size, the
624 		//		file is structurally defective and should be rejected at load time.
625 		if (inst != sf2->Instruments)
626 		{
627 			if (inst->BagIndex < (inst - 1)->BagIndex)
628 			{
629 				throw CBadForm();
630 			}
631 		}
632 	}
633 }
634 
ParseShdr(SFFile * sf2,FileReader * f,DWORD chunkid,DWORD chunklen)635 static void ParseShdr(SFFile *sf2, FileReader *f, DWORD chunkid, DWORD chunklen)
636 {
637 	int i;
638 	SFSample *sample;
639 
640 	// Section 7.10, page 29:
641 	// If the SHDR sub-chunk is missing, or its is size is not a multiple of 46
642 	// bytes the file should be rejected as structurally unsound.
643 	if (chunklen % 46 != 0)
644 	{
645 		throw CBadForm();
646 	}
647 
648 	sf2->NumSamples = chunklen / 46;
649 	sf2->Samples = sample = new SFSample[sf2->NumSamples];
650 	for (i = sf2->NumSamples; i != 0; --i, ++sample)
651 	{
652 		sample->InMemoryData = NULL;
653 		read_name(f, sample->Name);
654 		sample->Start = read_dword(f);
655 		sample->End = read_dword(f);
656 		sample->StartLoop = read_dword(f);
657 		sample->EndLoop = read_dword(f);
658 		sample->SampleRate = read_dword(f);
659 		sample->OriginalPitch = read_byte(f);
660 		sample->PitchCorrection = read_char(f);
661 		sample->SampleLink = read_uword(f);
662 		sample->SampleType = read_uword(f);
663 
664 		if (sample->SampleRate == 0)
665 		{
666 			// Section 7.10, page 29:
667 			// A value of zero is illegal. If an illegal or impractical value is
668 			// encountered, the nearest practical value should be used.
669 			sample->SampleRate = 400;
670 		}
671 		if (sample->OriginalPitch > 127)
672 		{
673 			// Section 7.10, page 29:
674 			// For unpitched sounds, a conventional value of 255 should be used
675 			// Values between 128 and 254 are illegal. Whenever an illegal value
676 			// or a value of 255 is encountered, the value 60 should be used.
677 			sample->OriginalPitch = 60;
678 		}
679 
680 		// Clamp sample positions to the available sample data.
681 		sample->Start = MIN(sample->Start, sf2->SizeSampleData - 1);
682 		sample->End = MIN(sample->End, sf2->SizeSampleData - 1);
683 		sample->StartLoop = MIN(sample->StartLoop, sf2->SizeSampleData - 1);
684 		sample->EndLoop = MIN(sample->EndLoop, sf2->SizeSampleData - 1);
685 
686 		if (sample->Start >= sample->End)
687 		{
688 			sample->SampleType |= SFST_Bad;
689 		}
690 	}
691 }
692 
693 
ReadSF2(const char * filename,FileReader * f)694 SFFile *ReadSF2(const char *filename, FileReader *f)
695 {
696 	SFFile *sf2 = NULL;
697 	DWORD filelen;
698 	DWORD chunklen;
699 
700 	try
701 	{
702 		// Read RIFF sfbk header
703 		if (read_id(f) != ID_RIFF)
704 		{
705 			return NULL;
706 		}
707 		filelen = read_dword(f);
708 		if (read_id(f) != ID_sfbk)
709 		{
710 			return NULL;
711 		}
712 		filelen -= 4;
713 
714 		// First chunk must be an INFO LIST
715 		check_list(f, ID_INFO, filelen, chunklen);
716 
717 		sf2 = new SFFile(filename);
718 
719 		ParseINFO(sf2, f, chunklen);
720 		filelen -= chunklen + 8;
721 
722 		// Second chunk must be a sdta LIST
723 		check_list(f, ID_sdta, filelen, chunklen);
724 		ParseSdta(sf2, f, chunklen);
725 
726 		// Third chunk must be a pdta LIST
727 		check_list(f, ID_pdta, filelen, chunklen);
728 		ParsePdta(sf2, f, chunklen);
729 
730 		// There should be no more chunks. If there are, we'll just ignore them rather than reject the file.
731 		if (!sf2->FinalStructureTest())
732 		{
733 			throw CBadForm();
734 		}
735 
736 		sf2->CheckBags();
737 		sf2->TranslatePercussions();
738 
739 		return sf2;
740 	}
741 	catch (CIOErr)
742 	{
743 		Printf("Error reading %s: %s\n", filename, strerror(errno));
744 	}
745 	catch (CBadForm)
746 	{
747 		Printf("%s is corrupted.\n", filename);
748 	}
749 	catch (CBadVer)
750 	{
751 		Printf("%s is not a SoundFont version 2 file.\n", filename);
752 	}
753 	if (sf2 != NULL)
754 	{
755 		delete sf2;
756 	}
757 	return NULL;
758 }
759 
SFFile(FString filename)760 SFFile::SFFile(FString filename)
761 : FontFile(filename)
762 {
763 	Presets = NULL;
764 	PresetBags = NULL;
765 	PresetGenerators = NULL;
766 	Instruments = NULL;
767 	InstrBags = NULL;
768 	InstrGenerators = NULL;
769 	Samples = NULL;
770 	MinorVersion = 0;
771 	SampleDataOffset = 0;
772 	SampleDataLSBOffset = 0;
773 	SizeSampleData = 0;
774 	SizeSampleDataLSB = 0;
775 	NumPresets = 0;
776 	NumPresetBags = 0;
777 	NumPresetGenerators = 0;
778 	NumInstruments = 0;
779 	NumInstrBags = 0;
780 	NumInstrGenerators = 0;
781 	NumSamples = 0;
782 }
783 
~SFFile()784 SFFile::~SFFile()
785 {
786 	if (Presets != NULL)
787 	{
788 		delete[] Presets;
789 	}
790 	if (PresetBags != NULL)
791 	{
792 		delete[] PresetBags;
793 	}
794 	if (PresetGenerators != NULL)
795 	{
796 		delete[] PresetGenerators;
797 	}
798 	if (Instruments != NULL)
799 	{
800 		delete[] Instruments;
801 	}
802 	if (InstrBags != NULL)
803 	{
804 		delete[] InstrBags;
805 	}
806 	if (InstrGenerators != NULL)
807 	{
808 		delete[] InstrGenerators;
809 	}
810 	if (Samples != NULL)
811 	{
812 		for (int i = 0; i < NumSamples; ++i)
813 		{
814 			if (Samples[i].InMemoryData != NULL)
815 			{
816 				delete[] Samples[i].InMemoryData;
817 			}
818 		}
819 		delete[] Samples;
820 	}
821 }
822 
FinalStructureTest()823 bool SFFile::FinalStructureTest()
824 {
825 	// All required chunks must be present.
826 	if (Presets == NULL || PresetBags == NULL || PresetGenerators == NULL ||
827 		Instruments == NULL || InstrBags == NULL || InstrGenerators == NULL ||
828 		Samples == NULL)
829 	{
830 		return false;
831 	}
832 	// What good is it if it has no sample data?
833 	if (SizeSampleData == 0)
834 	{
835 		return false;
836 	}
837 	return true;
838 }
839 
SetOrder(int order,int drum,int bank,int program)840 void SFFile::SetOrder(int order, int drum, int bank, int program)
841 {
842 	if (drum)
843 	{
844 		for (int i = 0; i < NumPresets; ++i)
845 		{
846 			if (Percussion[i].Generators.drumset == bank && Percussion[i].Generators.key == program)
847 			{
848 				Percussion[i].LoadOrder = order;
849 			}
850 		}
851 	}
852 	else
853 	{
854 		for (int i = 0; i < NumPresets; ++i)
855 		{
856 			if (Presets[i].Program == program && Presets[i].Bank == bank)
857 			{
858 				Presets[i].LoadOrder = order;
859 			}
860 		}
861 	}
862 }
863 
SetAllOrders(int order)864 void SFFile::SetAllOrders(int order)
865 {
866 	for (int i = 0; i < NumPresets; ++i)
867 	{
868 		Presets[i].LoadOrder = order;
869 	}
870 	for (unsigned int i = 0; i < Percussion.Size(); ++i)
871 	{
872 		Percussion[i].LoadOrder = order;
873 	}
874 }
875 
LoadInstrument(Renderer * song,int drum,int bank,int program)876 Instrument *SFFile::LoadInstrument(Renderer *song, int drum, int bank, int program)
877 {
878 	return LoadInstrumentOrder(song, -1, drum, bank, program);
879 }
880 
LoadInstrumentOrder(Renderer * song,int order,int drum,int bank,int program)881 Instrument *SFFile::LoadInstrumentOrder(Renderer *song, int order, int drum, int bank, int program)
882 {
883 	if (drum)
884 	{
885 		for (unsigned int i = 0; i < Percussion.Size(); ++i)
886 		{
887 			if ((order < 0 || Percussion[i].LoadOrder == order) &&
888 				Percussion[i].Generators.drumset == bank &&
889 				Percussion[i].Generators.key == program)
890 			{
891 				return LoadPercussion(song, &Percussion[i]);
892 			}
893 		}
894 	}
895 	else
896 	{
897 		for (int i = 0; i < NumPresets - 1; ++i)
898 		{
899 			if ((order < 0 || Presets[i].LoadOrder == order) &&
900 				Presets[i].Bank == bank &&
901 				Presets[i].Program == program)
902 			{
903 				return LoadPreset(song, &Presets[i]);
904 			}
905 		}
906 	}
907 	return NULL;
908 }
909 
910 //===========================================================================
911 //
912 // SFFile :: CheckBags
913 //
914 // For all preset and instrument zones, extract the velocity and key ranges
915 // and instrument and sample targets.
916 //
917 //===========================================================================
918 
CheckBags()919 void SFFile::CheckBags()
920 {
921 	int i;
922 
923 	for (i = 0; i < NumPresets - 1; ++i)
924 	{
925 		if (Presets[i].BagIndex >= Presets[i + 1].BagIndex)
926 		{ // Preset is empty.
927 			Presets[i].Bank = ~0;
928 		}
929 		else
930 		{
931 			CheckZones(Presets[i].BagIndex, Presets[i + 1].BagIndex, 0);
932 			Presets[i].bHasGlobalZone = PresetBags[Presets[i].BagIndex].Target < 0;
933 		}
934 	}
935 	for (i = 0; i < NumInstruments - 1; ++i)
936 	{
937 		if (Instruments[i].BagIndex >= Instruments[i + 1].BagIndex)
938 		{ // Instrument is empty.
939 		}
940 		else
941 		{
942 			CheckZones(Instruments[i].BagIndex, Instruments[i + 1].BagIndex, 1);
943 			Instruments[i].bHasGlobalZone = InstrBags[Instruments[i].BagIndex].Target < 0;
944 		}
945 	}
946 }
947 
948 //===========================================================================
949 //
950 // SFFile :: CheckZones
951 //
952 // For every zone in the bag, extract the velocity and key ranges and
953 // instrument and sample targets.
954 //
955 //===========================================================================
956 
CheckZones(int start,int stop,bool instr)957 void SFFile::CheckZones(int start, int stop, bool instr)
958 {
959 	SFBag *bag;
960 	SFGenList *gens;
961 	SFGenerator terminal_gen;
962 	int zone_start, zone_stop;
963 	int i, j;
964 
965 	if (!instr)
966 	{
967 		bag = PresetBags;
968 		gens = PresetGenerators;
969 		terminal_gen = GEN_instrument;
970 	}
971 	else
972 	{
973 		bag = InstrBags;
974 		gens = InstrGenerators;
975 		terminal_gen = GEN_sampleID;
976 	}
977 	for (i = start; i < stop; ++i)
978 	{
979 		zone_start = bag[i].GenIndex;
980 		zone_stop = bag[i + 1].GenIndex;
981 
982 		if (zone_start > zone_stop)
983 		{
984 			// Skip empty zones, and mark them inaccessible.
985 			bag[i].KeyRange.Lo = 255;
986 			bag[i].KeyRange.Hi = 255;
987 			bag[i].VelRange.Lo = 255;
988 			bag[i].VelRange.Hi = 255;
989 			continue;
990 		}
991 
992 		// According to the specs, if keyRange is present, it must be the first generator.
993 		// If velRange is present, it may only be preceded by keyRange. In real life, there
994 		// exist Soundfonts that violate this rule, so we need to scan every generator.
995 
996 		// Preload ranges from the global zone.
997 		if (i != start && bag[start].Target < 0)
998 		{
999 			bag[i].KeyRange = bag[start].KeyRange;
1000 			bag[i].VelRange = bag[start].VelRange;
1001 		}
1002 		for (j = zone_start; j < zone_stop; ++j)
1003 		{
1004 			if (gens[j].Oper == GEN_keyRange)
1005 			{
1006 				bag[i].KeyRange = gens[j].Range;
1007 			}
1008 			else if (gens[j].Oper == GEN_velRange)
1009 			{
1010 				bag[i].VelRange = gens[j].Range;
1011 			}
1012 			else if (gens[j].Oper == terminal_gen)
1013 			{
1014 				if (terminal_gen == GEN_instrument && gens[j].uAmount < NumInstruments - 1)
1015 				{
1016 					bag[i].Target = gens[j].uAmount;
1017 				}
1018 				else if (terminal_gen == GEN_sampleID && gens[j].uAmount < NumSamples - 1)
1019 				{
1020 					bag[i].Target = gens[j].uAmount;
1021 				}
1022 				break;
1023 			}
1024 		}
1025 		if (bag[i].Target < 0 && i != start)
1026 		{
1027 			// Only the first zone may be targetless. If any other zones are,
1028 			// make them inaccessible.
1029 			bag[i].KeyRange.Lo = 255;
1030 			bag[i].KeyRange.Hi = 255;
1031 			bag[i].VelRange.Lo = 255;
1032 			bag[i].VelRange.Hi = 255;
1033 		}
1034 
1035 		// Check for swapped ranges. (Should we fix them or ignore them?)
1036 		if (bag[i].KeyRange.Lo > bag[i].KeyRange.Hi)
1037 		{
1038 			swapvalues(bag[i].KeyRange.Lo, bag[i].KeyRange.Hi);
1039 		}
1040 		if (bag[i].VelRange.Lo > bag[i].VelRange.Hi)
1041 		{
1042 			swapvalues(bag[i].VelRange.Lo, bag[i].VelRange.Hi);
1043 		}
1044 	}
1045 }
1046 
1047 //===========================================================================
1048 //
1049 // SFFile :: TranslatePercussions
1050 //
1051 // For every percussion instrument, compile a set of composite generators
1052 // for each key, to make creating TiMidity instruments for individual
1053 // percussion parts easier.
1054 //
1055 //===========================================================================
1056 
TranslatePercussions()1057 void SFFile::TranslatePercussions()
1058 {
1059 	for (int i = 0; i < NumPresets - 1; ++i)
1060 	{
1061 		if (Presets[i].Bank == 128 && Presets[i].Program < 128)
1062 		{
1063 			TranslatePercussionPreset(&Presets[i]);
1064 		}
1065 	}
1066 }
1067 
1068 //===========================================================================
1069 //
1070 // SFFile :: TranslatePercussionPreset
1071 //
1072 // Compile a set of composite generators for each key of this percussion
1073 // instrument. Note that one instrument is actually an entire drumset.
1074 //
1075 //===========================================================================
1076 
TranslatePercussionPreset(SFPreset * preset)1077 void SFFile::TranslatePercussionPreset(SFPreset *preset)
1078 {
1079 	SFPerc perc;
1080 	int i;
1081 	bool has_global;
1082 
1083 	perc.LoadOrder = preset->LoadOrder;
1084 	i = preset->BagIndex;
1085 	has_global = false;
1086 
1087 	for (i = preset->BagIndex; i < (preset + 1)->BagIndex; ++i)
1088 	{
1089 		if (PresetBags[i].Target < 0)
1090 		{ // This preset zone has no instrument.
1091 			continue;
1092 		}
1093 		if (PresetBags[i].KeyRange.Lo > 127 || PresetBags[i].VelRange.Lo > 127)
1094 		{ // This preset zone is inaccesible.
1095 			continue;
1096 		}
1097 		TranslatePercussionPresetZone(preset, &PresetBags[i]);
1098 	}
1099 }
1100 
1101 //===========================================================================
1102 //
1103 // SFFile :: TranslatePercussionPresetZone
1104 //
1105 // Create a composite generator set for all keys and velocity ranges in this
1106 // preset zone that intersect with this zone's instrument.
1107 //
1108 //===========================================================================
1109 
TranslatePercussionPresetZone(SFPreset * preset,SFBag * pzone)1110 void SFFile::TranslatePercussionPresetZone(SFPreset *preset, SFBag *pzone)
1111 {
1112 	int key, i;
1113 
1114 	for (key = pzone->KeyRange.Lo; key <= pzone->KeyRange.Hi; ++key)
1115 	{
1116 		SFInst *inst = &Instruments[pzone->Target];
1117 		for (i = inst->BagIndex; i < (inst + 1)->BagIndex; ++i)
1118 		{
1119 			if (InstrBags[i].Target < 0)
1120 			{ // This instrument zone has no sample.
1121 				continue;
1122 			}
1123 			if (InstrBags[i].KeyRange.Lo > key || InstrBags[i].KeyRange.Hi < key)
1124 			{ // This instrument zone does not contain the key we want.
1125 				continue;
1126 			}
1127 			if (InstrBags[i].VelRange.Lo > pzone->VelRange.Hi ||
1128 				InstrBags[i].VelRange.Hi < pzone->VelRange.Lo)
1129 			{ // This instrument zone does not intersect the current velocity range.
1130 				continue;
1131 			}
1132 			// An intersection! Add the composite generator for this key and velocity range.
1133 			SFPerc perc;
1134 			perc.LoadOrder = preset->LoadOrder;
1135 			perc.Preset = preset;
1136 			perc.Generators = DefaultGenerators;
1137 			if (inst->bHasGlobalZone)
1138 			{
1139 				SetInstrumentGenerators(&perc.Generators, InstrBags[inst->BagIndex].GenIndex, InstrBags[inst->BagIndex + 1].GenIndex);
1140 			}
1141 			SetInstrumentGenerators(&perc.Generators, InstrBags[i].GenIndex, InstrBags[i + 1].GenIndex);
1142 			AddPresetGenerators(&perc.Generators, pzone->GenIndex, (pzone + 1)->GenIndex, preset);
1143 			perc.Generators.drumset = (BYTE)preset->Program;
1144 			perc.Generators.key = key;
1145 			perc.Generators.velRange.Lo = MAX(pzone->VelRange.Lo, InstrBags[i].VelRange.Lo);
1146 			perc.Generators.velRange.Hi = MIN(pzone->VelRange.Hi, InstrBags[i].VelRange.Hi);
1147 			perc.Generators.sampleID = InstrBags[i].Target;
1148 			Percussion.Push(perc);
1149 		}
1150 	}
1151 }
1152 
SetInstrumentGenerators(SFGenComposite * composite,int start,int stop)1153 void SFFile::SetInstrumentGenerators(SFGenComposite *composite, int start, int stop)
1154 {
1155 	// Proceed from first to last; later generators override earlier ones.
1156 	SFGenList *gen = &InstrGenerators[start];
1157 	for (int i = stop - start; i != 0; --i, ++gen)
1158 	{
1159 		if (gen->Oper >= GEN_NumGenerators)
1160 		{ // Unknown generator.
1161 			continue;
1162 		}
1163 		if (GenDefs[gen->Oper].StructIndex >= sizeof(SFGenComposite)/2)
1164 		{ // Generator is either unused or ignored.
1165 			continue;
1166 		}
1167 		// Set the generator
1168 		((WORD *)composite)[GenDefs[gen->Oper].StructIndex] = gen->uAmount;
1169 		if (gen->Oper == GEN_sampleID)
1170 		{ // Anything past sampleID is ignored.
1171 			break;
1172 		}
1173 	}
1174 }
1175 
AddPresetGenerators(SFGenComposite * composite,int start,int stop,SFPreset * preset)1176 void SFFile::AddPresetGenerators(SFGenComposite *composite, int start, int stop, SFPreset *preset)
1177 {
1178 	bool gen_set[GEN_NumGenerators] = { false, };
1179 	AddPresetGenerators(composite, start, stop, gen_set);
1180 	if (preset->bHasGlobalZone)
1181 	{
1182 		AddPresetGenerators(composite, PresetBags[preset->BagIndex].GenIndex, PresetBags[preset->BagIndex + 1].GenIndex, gen_set);
1183 	}
1184 }
1185 
AddPresetGenerators(SFGenComposite * composite,int start,int stop,bool gen_set[GEN_NumGenerators])1186 void SFFile::AddPresetGenerators(SFGenComposite *composite, int start, int stop, bool gen_set[GEN_NumGenerators])
1187 {
1188 	// Proceed from last to first; later generators override earlier ones.
1189 	SFGenList *gen = &PresetGenerators[stop - 1];
1190 	const GenDef *def;
1191 
1192 	for (int i = stop - start; i != 0; --i, --gen)
1193 	{
1194 		if (gen->Oper >= GEN_NumGenerators)
1195 		{ // Unknown generator.
1196 			continue;
1197 		}
1198 		if (gen_set[gen->Oper])
1199 		{ // Generator was already set.
1200 			continue;
1201 		}
1202 		def = &GenDefs[gen->Oper];
1203 		if (def->StructIndex >= sizeof(SFGenComposite)/2)
1204 		{ // Generator is either unused or ignored.
1205 			continue;
1206 		}
1207 		if (def->Flags & GENF_InstrOnly)
1208 		{ // Generator is not valid at the preset level.
1209 			continue;
1210 		}
1211 		// Add to instrument/default generator.
1212 		int added = ((SWORD *)composite)[def->StructIndex] + gen->Amount;
1213 		// Clamp to proper range.
1214 		if (added <= -32768 && def->Flags & GENF_32768_Ok)
1215 		{
1216 			added = -32768;
1217 		}
1218 		else
1219 		{
1220 			added = clamp<int>(added, def->Min, def->Max);
1221 		}
1222 		((SWORD *)composite)[def->StructIndex] = added;
1223 		gen_set[gen->Oper] = true;
1224 		if (gen->Oper == GEN_instrument)
1225 		{ // Anything past the instrument generator is ignored.
1226 			break;
1227 		}
1228 	}
1229 }
1230 
LoadPercussion(Renderer * song,SFPerc * perc)1231 Instrument *SFFile::LoadPercussion(Renderer *song, SFPerc *perc)
1232 {
1233 	unsigned int i;
1234 	int drumkey;
1235 	int drumset;
1236 	int j;
1237 
1238 	Instrument *ip = new Instrument;
1239 	ip->samples = 0;
1240 	drumkey = perc->Generators.key;
1241 	drumset = perc->Generators.drumset;
1242 
1243 	// Count all percussion composites that match this one's key and set.
1244 	for (i = 0; i < Percussion.Size(); ++i)
1245 	{
1246 		if (Percussion[i].Generators.key == drumkey &&
1247 			Percussion[i].Generators.drumset == drumset &&
1248 			Percussion[i].Generators.sampleID < NumSamples)
1249 		{
1250 			SFSample *sfsamp = &Samples[Percussion[i].Generators.sampleID];
1251 			if (sfsamp->InMemoryData == NULL)
1252 			{
1253 				LoadSample(sfsamp);
1254 			}
1255 			if (sfsamp->InMemoryData != NULL)
1256 			{
1257 				ip->samples++;
1258 			}
1259 		}
1260 	}
1261 	if (ip->samples == 0)
1262 	{ // Nothing here to play.
1263 		delete ip;
1264 		return NULL;
1265 	}
1266 	ip->sample = (Sample *)safe_malloc(sizeof(Sample) * ip->samples);
1267 	memset(ip->sample, 0, sizeof(Sample) * ip->samples);
1268 
1269 	// Fill in Sample structure for each composite.
1270 	for (j = 0, i = 0; i < Percussion.Size(); ++i)
1271 	{
1272 		SFPerc *zone = &Percussion[i];
1273 		SFGenComposite *gen = &zone->Generators;
1274 		if (gen->key != drumkey ||
1275 			gen->drumset != drumset ||
1276 			gen->sampleID >= NumSamples)
1277 		{
1278 			continue;
1279 		}
1280 		SFSample *sfsamp = &Samples[gen->sampleID];
1281 		if (sfsamp->InMemoryData == NULL)
1282 		{
1283 			continue;
1284 		}
1285 		Sample *sp = ip->sample + j++;
1286 
1287 		// Set velocity range
1288 		sp->low_vel = gen->velRange.Lo;
1289 		sp->high_vel = gen->velRange.Hi;
1290 
1291 		// Set frequency range
1292 		sp->low_freq = note_to_freq(gen->key);
1293 		sp->high_freq = sp->low_freq;
1294 
1295 		ApplyGeneratorsToRegion(gen, sfsamp, song, sp);
1296 	}
1297 	assert(j == ip->samples);
1298 	return ip;
1299 }
1300 
1301 //===========================================================================
1302 //
1303 // SFFile :: LoadPreset
1304 //
1305 //===========================================================================
1306 
LoadPreset(Renderer * song,SFPreset * preset)1307 Instrument *SFFile::LoadPreset(Renderer *song, SFPreset *preset)
1308 {
1309 	SFInst *inst;
1310 	SFSample *sfsamp;
1311 	SFGenComposite gen;
1312 	int i, j, k;
1313 
1314 	Instrument *ip = new Instrument;
1315 	ip->samples = 0;
1316 
1317 	// Count the number of regions we'll need.
1318 	for (i = preset->BagIndex; i < (preset + 1)->BagIndex; ++i)
1319 	{
1320 		if (PresetBags[i].Target < 0)
1321 		{ // Preset zone has no instrument.
1322 			continue;
1323 		}
1324 		inst = &Instruments[PresetBags[i].Target];
1325 		for (j = inst->BagIndex; j < (inst + 1)->BagIndex; ++j)
1326 		{
1327 			if (InstrBags[j].Target < 0)
1328 			{ // Instrument zone has no sample.
1329 				continue;
1330 			}
1331 			if (InstrBags[j].KeyRange.Lo <= PresetBags[i].KeyRange.Hi &&
1332 				InstrBags[j].KeyRange.Hi >= PresetBags[i].KeyRange.Lo &&
1333 				InstrBags[j].VelRange.Lo <= PresetBags[i].VelRange.Hi &&
1334 				InstrBags[j].VelRange.Hi >= PresetBags[i].VelRange.Lo)
1335 			{ // The preset and instrument zones intersect!
1336 				sfsamp = &Samples[InstrBags[j].Target];
1337 				if (sfsamp->InMemoryData == NULL)
1338 				{
1339 					LoadSample(sfsamp);
1340 				}
1341 				if (sfsamp->InMemoryData != NULL)
1342 				{
1343 					ip->samples++;
1344 				}
1345 			}
1346 		}
1347 	}
1348 	if (ip->samples == 0)
1349 	{ // Nothing here to play.
1350 		delete ip;
1351 		return NULL;
1352 	}
1353 	// Allocate the regions and define them
1354 	ip->sample = (Sample *)safe_malloc(sizeof(Sample) * ip->samples);
1355 	memset(ip->sample, 0, sizeof(Sample) * ip->samples);
1356 	k = 0;
1357 	for (i = preset->BagIndex; i < (preset + 1)->BagIndex; ++i)
1358 	{
1359 		if (PresetBags[i].Target < 0)
1360 		{ // Preset zone has no instrument.
1361 			continue;
1362 		}
1363 		inst = &Instruments[PresetBags[i].Target];
1364 		for (j = inst->BagIndex; j < (inst + 1)->BagIndex; ++j)
1365 		{
1366 			if (InstrBags[j].Target < 0)
1367 			{ // Instrument zone has no sample.
1368 				continue;
1369 			}
1370 			if (InstrBags[j].KeyRange.Lo <= PresetBags[i].KeyRange.Hi &&
1371 				InstrBags[j].KeyRange.Hi >= PresetBags[i].KeyRange.Lo &&
1372 				InstrBags[j].VelRange.Lo <= PresetBags[i].VelRange.Hi &&
1373 				InstrBags[j].VelRange.Hi >= PresetBags[i].VelRange.Lo)
1374 			{ // The preset and instrument zones intersect!
1375 				sfsamp = &Samples[InstrBags[j].Target];
1376 				if (sfsamp->InMemoryData == NULL)
1377 				{
1378 					continue;
1379 				}
1380 				Sample *sp = ip->sample + k++;
1381 
1382 				// Set velocity range
1383 				sp->low_vel = MAX(InstrBags[j].VelRange.Lo, PresetBags[i].VelRange.Lo);
1384 				sp->high_vel = MIN(InstrBags[j].VelRange.Hi, PresetBags[i].VelRange.Hi);
1385 
1386 				// Set frequency range
1387 				sp->low_freq = note_to_freq(MAX(InstrBags[j].KeyRange.Lo, PresetBags[i].KeyRange.Lo));
1388 				sp->high_freq = note_to_freq(MIN(InstrBags[j].KeyRange.Hi, PresetBags[i].KeyRange.Hi));
1389 
1390 				gen = DefaultGenerators;
1391 				if (inst->bHasGlobalZone)
1392 				{
1393 					SetInstrumentGenerators(&gen, InstrBags[inst->BagIndex].GenIndex, InstrBags[inst->BagIndex + 1].GenIndex);
1394 				}
1395 				SetInstrumentGenerators(&gen, InstrBags[j].GenIndex, InstrBags[j + 1].GenIndex);
1396 				AddPresetGenerators(&gen, PresetBags[i].GenIndex, PresetBags[i + 1].GenIndex, preset);
1397 				ApplyGeneratorsToRegion(&gen, sfsamp, song, sp);
1398 			}
1399 		}
1400 	}
1401 	assert(k == ip->samples);
1402 	return ip;
1403 }
1404 
1405 //===========================================================================
1406 //
1407 // SFFile :: ApplyGeneratorsToRegion
1408 //
1409 // The caller must set the key and velocity ranges. Other information for
1410 // the TiMidity sample will be filled in using the generators given.
1411 //
1412 // FIXME: At least try to do something useful with every parameter.
1413 //
1414 //===========================================================================
1415 
ApplyGeneratorsToRegion(SFGenComposite * gen,SFSample * sfsamp,Renderer * song,Sample * sp)1416 void SFFile::ApplyGeneratorsToRegion(SFGenComposite *gen, SFSample *sfsamp, Renderer *song, Sample *sp)
1417 {
1418 	sp->type = INST_SF2;
1419 
1420 	// Set loop and sample points
1421 	int start, end;
1422 	start = gen->startAddrsOffset + gen->startAddrsCoarseOffset * 32768;
1423 	end = gen->endAddrsOffset + gen->endAddrsCoarseOffset * 32768;
1424 	start = MAX<int>(sfsamp->Start, sfsamp->Start + start);
1425 	end = MIN<int>(sfsamp->End, sfsamp->End + end);
1426 	sp->loop_start = MAX<int>(start, sfsamp->StartLoop + gen->startLoopAddrsOffset + gen->startLoopAddrsCoarseOffset * 32768);
1427 	sp->loop_end = MIN<int>(end, sfsamp->EndLoop + gen->endLoopAddrsOffset + gen->endLoopAddrsCoarseOffset * 32768);
1428 
1429 	sp->loop_start = (sp->loop_start - start) << FRACTION_BITS;
1430 	sp->loop_end = (sp->loop_end - start) << FRACTION_BITS;
1431 	sp->data_length = (end - start) << FRACTION_BITS;
1432 	sp->data = sfsamp->InMemoryData + start - sfsamp->Start;
1433 	if (gen->overridingRootKey >= 0 && gen->overridingRootKey <= 127)
1434 	{
1435 		sp->scale_note = gen->overridingRootKey;
1436 	}
1437 	else
1438 	{
1439 		sp->scale_note = sfsamp->OriginalPitch;
1440 	}
1441 	sp->root_freq = note_to_freq(sp->scale_note);
1442 	sp->sample_rate = sfsamp->SampleRate;
1443 	sp->key_group = gen->exclusiveClass;
1444 
1445 	// Set key scaling
1446 	if (gen->keynum >= 0 && gen->keynum <= 127)
1447 	{
1448 		sp->scale_note = gen->keynum;
1449 		sp->scale_factor = 0;
1450 	}
1451 	else if (gen->scaleTuning >= 0)
1452 	{
1453 		sp->scale_factor = gen->scaleTuning * 1024 / 100;
1454 		// Does the root key also serve as the scale key? Assuming it does here.
1455 	}
1456 	else
1457 	{
1458 		sp->scale_factor = 1024;
1459 		sp->scale_note = 60;
1460 	}
1461 
1462 	// Set panning
1463 	sp->panning = gen->pan;
1464 
1465 	// Set volume envelope
1466 	sp->envelope.sf2.delay_vol = gen->delayVolEnv;
1467 	sp->envelope.sf2.attack_vol = gen->attackVolEnv;
1468 	sp->envelope.sf2.hold_vol = gen->holdVolEnv;
1469 	sp->envelope.sf2.decay_vol = gen->decayVolEnv;
1470 	sp->envelope.sf2.sustain_vol = gen->sustainVolEnv;
1471 	sp->envelope.sf2.release_vol = gen->releaseVolEnv;
1472 
1473 	// Set sample modes
1474 	if (gen->sampleModes == 1)
1475 	{
1476 		sp->modes = PATCH_LOOPEN | PATCH_SUSTAIN | PATCH_NO_SRELEASE;
1477 	}
1478 	else if (gen->sampleModes == 3)
1479 	{
1480 		sp->modes = PATCH_LOOPEN | PATCH_SUSTAIN;
1481 	}
1482 	else
1483 	{
1484 		sp->modes = PATCH_SUSTAIN;
1485 	}
1486 
1487 	// Set tuning (in cents)
1488 	sp->tune = gen->coarseTune * 100 + gen->fineTune;
1489 
1490 	sp->velocity = (SBYTE)gen->velocity;
1491 	sp->initial_attenuation = gen->initialAttenuation;
1492 }
1493 
1494 //===========================================================================
1495 //
1496 // SFFile :: LoadSample
1497 //
1498 // Loads a sample's data and converts it from 16/24-bit to floating point.
1499 //
1500 //===========================================================================
1501 
LoadSample(SFSample * sample)1502 void SFFile::LoadSample(SFSample *sample)
1503 {
1504 	FileReader *fp = pathExpander.openFileReader(Filename, NULL);
1505 	DWORD i;
1506 
1507 	if (fp == NULL)
1508 	{
1509 		return;
1510 	}
1511 	sample->InMemoryData = new float[sample->End - sample->Start + 1];
1512 	fp->Seek(SampleDataOffset + sample->Start * 2, SEEK_SET);
1513 	// Load 16-bit sample data.
1514 	for (i = 0; i < sample->End - sample->Start; ++i)
1515 	{
1516 		SWORD samp;
1517 		*fp >> samp;
1518 		sample->InMemoryData[i] = samp / 32768.f;
1519 	}
1520 	if (SampleDataLSBOffset != 0)
1521 	{ // Load lower 8 bits of 24-bit sample data.
1522 		fp->Seek(SampleDataLSBOffset + sample->Start, SEEK_SET);
1523 		for (i = 0; i < sample->End - sample->Start; ++i)
1524 		{
1525 			BYTE samp;
1526 			*fp >> samp;
1527 			sample->InMemoryData[i] = ((((SDWORD(sample->InMemoryData[i] * 32768) << 8) | samp) << 8) >> 8) / 8388608.f;
1528 		}
1529 	}
1530 	// Final 0 byte is for interpolation.
1531 	sample->InMemoryData[i] = 0;
1532 	delete fp;
1533 }
1534