1 /*
2 
3     TiMidity -- Experimental MIDI to WAVE converter
4     Copyright (C) 1995 Tuukka Toivonen <toivonen@clinet.fi>
5 
6     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10 
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15 
16     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software
18     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 
20    instrum.h
21 
22    */
23 
24 #include <stdlib.h>
25 #include <string.h>
26 
27 #include "timidity.h"
28 
29 #define __Sound_SetError(x)
30 
31 namespace LibTimidity
32 {
33 
34 /*-------------------------------------------------------------------------*/
35 /* * * * * * * * * * * * * * * * * load_riff.h * * * * * * * * * * * * * * */
36 /*-------------------------------------------------------------------------*/
37 struct RIFF_Chunk
38 {
39 	uint32 magic;
40 	uint32 length;
41 	uint32 subtype;
42 	uint8  *data;
43 	RIFF_Chunk *child;
44 	RIFF_Chunk *next;
45 };
46 
47 extern RIFF_Chunk* LoadRIFF(FILE *src);
48 extern void FreeRIFF(RIFF_Chunk *chunk);
49 extern void PrintRIFF(RIFF_Chunk *chunk, int level);
50 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
51 
52 /*-------------------------------------------------------------------------*/
53 /* * * * * * * * * * * * * * * * * load_riff.c * * * * * * * * * * * * * * */
54 /*-------------------------------------------------------------------------*/
55 #define RIFF        0x46464952        /* "RIFF" */
56 #define LIST        0x5453494c        /* "LIST" */
57 
AllocRIFFChunk()58 static RIFF_Chunk *AllocRIFFChunk()
59 {
60 	RIFF_Chunk *chunk = (RIFF_Chunk *)malloc(sizeof(*chunk));
61 	if (!chunk)
62 	{
63 		__Sound_SetError(ERR_OUT_OF_MEMORY);
64 		return NULL;
65 	}
66 	memset(chunk, 0, sizeof(*chunk));
67 	return chunk;
68 }
69 
FreeRIFFChunk(RIFF_Chunk * chunk)70 static void FreeRIFFChunk(RIFF_Chunk *chunk)
71 {
72 	if (chunk->child)
73 	{
74 		FreeRIFFChunk(chunk->child);
75 	}
76 	if (chunk->next)
77 	{
78 		FreeRIFFChunk(chunk->next);
79 	}
80 	free(chunk);
81 	chunk = NULL;
82 }
83 
ChunkHasSubType(uint32 magic)84 static int ChunkHasSubType(uint32 magic)
85 {
86 	static uint32 chunk_list[] = {
87 		RIFF, LIST
88 	};
89 	int i;
90 	for ( i = 0; i < sizeof(chunk_list) / sizeof(chunk_list[0]); ++i ) {
91 		if ( magic == chunk_list[i] ) {
92 			return 1;
93 		}
94 	}
95 	return 0;
96 }
97 
ChunkHasSubChunks(uint32 magic)98 static int ChunkHasSubChunks(uint32 magic)
99 {
100 	static uint32 chunk_list[] = {
101 		RIFF, LIST
102 	};
103 	int i;
104 	for ( i = 0; i < sizeof(chunk_list) / sizeof(chunk_list[0]); ++i ) {
105 		if ( magic == chunk_list[i] ) {
106 			return 1;
107 		}
108 	}
109 	return 0;
110 }
111 
LoadSubChunks(RIFF_Chunk * chunk,uint8 * data,uint32 left)112 static void LoadSubChunks(RIFF_Chunk *chunk, uint8 *data, uint32 left)
113 {
114 	uint8 *subchunkData;
115 	uint32 subchunkDataLen;
116 
117 	while ( left > 8 ) {
118 		RIFF_Chunk *child = AllocRIFFChunk();
119 		RIFF_Chunk *next, *prev = NULL;
120 		for ( next = chunk->child; next; next = next->next ) {
121 			prev = next;
122 		}
123 		if ( prev ) {
124 			prev->next = child;
125 		} else {
126 			chunk->child = child;
127 		}
128 
129 		child->magic = (data[0] <<  0) |
130 						(data[1] <<  8) |
131 						(data[2] << 16) |
132 						(data[3] << 24);
133 		data += 4;
134 		left -= 4;
135 		child->length = (data[0] <<  0) |
136 						(data[1] <<  8) |
137 						(data[2] << 16) |
138 						(data[3] << 24);
139 		data += 4;
140 		left -= 4;
141 		child->data = data;
142 
143 		if ( child->length > left ) {
144 			child->length = left;
145 		}
146 
147 		subchunkData = child->data;
148 		subchunkDataLen = child->length;
149 		if ( ChunkHasSubType(child->magic) && subchunkDataLen >= 4 ) {
150 			child->subtype = (subchunkData[0] <<  0) |
151 						(subchunkData[1] <<  8) |
152 						(subchunkData[2] << 16) |
153 						(subchunkData[3] << 24);
154 			subchunkData += 4;
155 			subchunkDataLen -= 4;
156 		}
157 		if ( ChunkHasSubChunks(child->magic) ) {
158 			LoadSubChunks(child, subchunkData, subchunkDataLen);
159 		}
160 
161 		data += (child->length + 1) & ~1;
162 		left -= (child->length + 1) & ~1;
163 	}
164 }
165 
LoadRIFF(FILE * src)166 RIFF_Chunk *LoadRIFF(FILE* src)
167 {
168 	RIFF_Chunk *chunk;
169 	uint8 *subchunkData;
170 	uint32 subchunkDataLen;
171 
172 	/* Allocate the chunk structure */
173 	chunk = AllocRIFFChunk();
174 
175 	/* Make sure the file is in RIFF format */
176 	fread(&chunk->magic, 4, 1, src);
177 	fread(&chunk->length, 4, 1, src);
178 	chunk->magic = LE_LONG(chunk->magic);
179 	chunk->length = LE_LONG(chunk->length);
180 	if ( chunk->magic != RIFF ) {
181 		__Sound_SetError("Not a RIFF file");
182 		FreeRIFFChunk(chunk);
183 		return NULL;
184 	}
185 	chunk->data = (uint8 *)malloc(chunk->length);
186 	if ( chunk->data == NULL ) {
187 		__Sound_SetError(ERR_OUT_OF_MEMORY);
188 		FreeRIFFChunk(chunk);
189 		return NULL;
190 	}
191 	if ( fread(chunk->data, chunk->length, 1, src) != 1 ) {
192 		__Sound_SetError(ERR_IO_ERROR);
193 		FreeRIFF(chunk);
194 		return NULL;
195 	}
196 	subchunkData = chunk->data;
197 	subchunkDataLen = chunk->length;
198 	if ( ChunkHasSubType(chunk->magic) && subchunkDataLen >= 4 ) {
199 		chunk->subtype = (subchunkData[0] <<  0) |
200 					(subchunkData[1] <<  8) |
201 					(subchunkData[2] << 16) |
202 					(subchunkData[3] << 24);
203 		subchunkData += 4;
204 		subchunkDataLen -= 4;
205 	}
206 	if ( ChunkHasSubChunks(chunk->magic) ) {
207 		LoadSubChunks(chunk, subchunkData, subchunkDataLen);
208 	}
209 	return chunk;
210 }
211 
FreeRIFF(RIFF_Chunk * chunk)212 void FreeRIFF(RIFF_Chunk *chunk)
213 {
214 	free(chunk->data);
215 	chunk->data = NULL;
216 	FreeRIFFChunk(chunk);
217 }
218 
219 /*-------------------------------------------------------------------------*/
220 /* * * * * * * * * * * * * * * * * load_dls.h  * * * * * * * * * * * * * * */
221 /*-------------------------------------------------------------------------*/
222 /* This code is based on the DLS spec version 1.1, available at:
223     http://www.midi.org/about-midi/dls/dlsspec.shtml
224 */
225 
226 /* Some typedefs so the public dls headers don't need to be modified */
227 #define FAR
228 typedef uint8   BYTE;
229 typedef int16   SHORT;
230 typedef uint16  USHORT;
231 typedef uint16  WORD;
232 typedef int32   LONG;
233 typedef uint32  ULONG;
234 typedef uint32  DWORD;
235 #define mmioFOURCC(A, B, C, D)    \
236     (((A) <<  0) | ((B) <<  8) | ((C) << 16) | ((D) << 24))
237 #define DEFINE_GUID(A, B, C, E, F, G, H, I, J, K, L, M)
238 
239 #include "dls1.h"
240 #include "dls2.h"
241 
242 struct WaveFMT
243 {
244 	WORD wFormatTag;
245 	WORD wChannels;
246 	DWORD dwSamplesPerSec;
247 	DWORD dwAvgBytesPerSec;
248 	WORD wBlockAlign;
249 	WORD wBitsPerSample;
250 };
251 
252 struct DLS_Wave
253 {
254 	WaveFMT *format;
255 	uint8 *data;
256 	uint32 length;
257 	WSMPL *wsmp;
258 	WLOOP *wsmp_loop;
259 };
260 
261 struct DLS_Region
262 {
263 	RGNHEADER *header;
264 	WAVELINK *wlnk;
265 	WSMPL *wsmp;
266 	WLOOP *wsmp_loop;
267 	CONNECTIONLIST *art;
268 	CONNECTION *artList;
269 };
270 
271 struct DLS_Instrument
272 {
273 	const char *name;
274 	INSTHEADER *header;
275 	DLS_Region *regions;
276 	CONNECTIONLIST *art;
277 	CONNECTION *artList;
278 };
279 
280 struct DLS_Data
281 {
282 	RIFF_Chunk *chunk;
283 
284 	uint32 cInstruments;
285 	DLS_Instrument *instruments;
286 
287 	POOLTABLE *ptbl;
288 	POOLCUE *ptblList;
289 	DLS_Wave *waveList;
290 
291 	const char *name;
292 	const char *artist;
293 	const char *copyright;
294 	const char *comments;
295 };
296 
297 extern DLS_Data* LoadDLS(FILE *src);
298 extern void FreeDLS(DLS_Data *chunk);
299 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
300 
301 /*-------------------------------------------------------------------------*/
302 /* * * * * * * * * * * * * * * * * load_dls.c  * * * * * * * * * * * * * * */
303 /*-------------------------------------------------------------------------*/
304 
305 #define FOURCC_LIST    0x5453494c   /* "LIST" */
306 #define FOURCC_FMT     0x20746D66   /* "fmt " */
307 #define FOURCC_DATA    0x61746164   /* "data" */
308 #define FOURCC_INFO    mmioFOURCC('I','N','F','O')
309 #define FOURCC_IARL    mmioFOURCC('I','A','R','L')
310 #define FOURCC_IART    mmioFOURCC('I','A','R','T')
311 #define FOURCC_ICMS    mmioFOURCC('I','C','M','S')
312 #define FOURCC_ICMT    mmioFOURCC('I','C','M','T')
313 #define FOURCC_ICOP    mmioFOURCC('I','C','O','P')
314 #define FOURCC_ICRD    mmioFOURCC('I','C','R','D')
315 #define FOURCC_IENG    mmioFOURCC('I','E','N','G')
316 #define FOURCC_IGNR    mmioFOURCC('I','G','N','R')
317 #define FOURCC_IKEY    mmioFOURCC('I','K','E','Y')
318 #define FOURCC_IMED    mmioFOURCC('I','M','E','D')
319 #define FOURCC_INAM    mmioFOURCC('I','N','A','M')
320 #define FOURCC_IPRD    mmioFOURCC('I','P','R','D')
321 #define FOURCC_ISBJ    mmioFOURCC('I','S','B','J')
322 #define FOURCC_ISFT    mmioFOURCC('I','S','F','T')
323 #define FOURCC_ISRC    mmioFOURCC('I','S','R','C')
324 #define FOURCC_ISRF    mmioFOURCC('I','S','R','F')
325 #define FOURCC_ITCH    mmioFOURCC('I','T','C','H')
326 
327 
FreeRegions(DLS_Instrument * instrument)328 static void FreeRegions(DLS_Instrument *instrument)
329 {
330 	if ( instrument->regions ) {
331 		free(instrument->regions);
332 		instrument->regions = NULL;
333 	}
334 }
335 
AllocRegions(DLS_Instrument * instrument)336 static void AllocRegions(DLS_Instrument *instrument)
337 {
338 	int datalen = (instrument->header->cRegions * sizeof(DLS_Region));
339 	FreeRegions(instrument);
340 	instrument->regions = (DLS_Region *)malloc(datalen);
341 	if ( instrument->regions ) {
342 		memset(instrument->regions, 0, datalen);
343 	}
344 }
345 
FreeInstruments(DLS_Data * data)346 static void FreeInstruments(DLS_Data *data)
347 {
348 	if ( data->instruments ) {
349 		uint32 i;
350 		for ( i = 0; i < data->cInstruments; ++i ) {
351 			FreeRegions(&data->instruments[i]);
352 		}
353 		free(data->instruments);
354 		data->instruments = NULL;
355 	}
356 }
357 
AllocInstruments(DLS_Data * data)358 static void AllocInstruments(DLS_Data *data)
359 {
360 	int datalen = (data->cInstruments * sizeof(DLS_Instrument));
361 	FreeInstruments(data);
362 	data->instruments = (DLS_Instrument *)malloc(datalen);
363 	if ( data->instruments ) {
364 		memset(data->instruments, 0, datalen);
365 	}
366 }
367 
FreeWaveList(DLS_Data * data)368 static void FreeWaveList(DLS_Data *data)
369 {
370 	if ( data->waveList ) {
371 		free(data->waveList);
372 		data->waveList = NULL;
373 	}
374 }
375 
AllocWaveList(DLS_Data * data)376 static void AllocWaveList(DLS_Data *data)
377 {
378 	int datalen = (data->ptbl->cCues * sizeof(DLS_Wave));
379 	FreeWaveList(data);
380 	data->waveList = (DLS_Wave *)malloc(datalen);
381 	if ( data->waveList ) {
382 		memset(data->waveList, 0, datalen);
383 	}
384 }
385 
Parse_colh(DLS_Data * data,RIFF_Chunk * chunk)386 static void Parse_colh(DLS_Data *data, RIFF_Chunk *chunk)
387 {
388 	data->cInstruments = LE_LONG(*(uint32 *)chunk->data);
389 	AllocInstruments(data);
390 }
391 
Parse_insh(DLS_Data * data,RIFF_Chunk * chunk,DLS_Instrument * instrument)392 static void Parse_insh(DLS_Data *data, RIFF_Chunk *chunk, DLS_Instrument *instrument)
393 {
394 	INSTHEADER *header = (INSTHEADER *)chunk->data;
395 	header->cRegions = LE_LONG(header->cRegions);
396 	header->Locale.ulBank = LE_LONG(header->Locale.ulBank);
397 	header->Locale.ulInstrument = LE_LONG(header->Locale.ulInstrument);
398 	instrument->header = header;
399 	AllocRegions(instrument);
400 }
401 
Parse_rgnh(DLS_Data * data,RIFF_Chunk * chunk,DLS_Region * region)402 static void Parse_rgnh(DLS_Data *data, RIFF_Chunk *chunk, DLS_Region *region)
403 {
404 	RGNHEADER *header = (RGNHEADER *)chunk->data;
405 	header->RangeKey.usLow = LE_SHORT(header->RangeKey.usLow);
406 	header->RangeKey.usHigh = LE_SHORT(header->RangeKey.usHigh);
407 	header->RangeVelocity.usLow = LE_SHORT(header->RangeVelocity.usLow);
408 	header->RangeVelocity.usHigh = LE_SHORT(header->RangeVelocity.usHigh);
409 	header->fusOptions = LE_SHORT(header->fusOptions);
410 	header->usKeyGroup = LE_SHORT(header->usKeyGroup);
411 	region->header = header;
412 }
413 
Parse_wlnk(DLS_Data * data,RIFF_Chunk * chunk,DLS_Region * region)414 static void Parse_wlnk(DLS_Data *data, RIFF_Chunk *chunk, DLS_Region *region)
415 {
416 	WAVELINK *wlnk = (WAVELINK *)chunk->data;
417 	wlnk->fusOptions = LE_SHORT(wlnk->fusOptions);
418 	wlnk->usPhaseGroup = LE_SHORT(wlnk->usPhaseGroup);
419 	wlnk->ulChannel = LE_LONG(wlnk->ulChannel);
420 	wlnk->ulTableIndex = LE_LONG(wlnk->ulTableIndex);
421 	region->wlnk = wlnk;
422 }
423 
Parse_wsmp(DLS_Data * data,RIFF_Chunk * chunk,WSMPL ** wsmp_ptr,WLOOP ** wsmp_loop_ptr)424 static void Parse_wsmp(DLS_Data *data, RIFF_Chunk *chunk, WSMPL **wsmp_ptr, WLOOP **wsmp_loop_ptr)
425 {
426 	uint32 i;
427 	WSMPL *wsmp = (WSMPL *)chunk->data;
428 	WLOOP *loop;
429 	wsmp->cbSize = LE_LONG(wsmp->cbSize);
430 	wsmp->usUnityNote = LE_SHORT(wsmp->usUnityNote);
431 	wsmp->sFineTune = LE_SHORT(wsmp->sFineTune);
432 	wsmp->lAttenuation = LE_LONG(wsmp->lAttenuation);
433 	wsmp->fulOptions = LE_LONG(wsmp->fulOptions);
434 	wsmp->cSampleLoops = LE_LONG(wsmp->cSampleLoops);
435 	loop = (WLOOP *)((uint8 *)chunk->data + wsmp->cbSize);
436 	*wsmp_ptr = wsmp;
437 	*wsmp_loop_ptr = loop;
438 	for ( i = 0; i < wsmp->cSampleLoops; ++i ) {
439 		loop->cbSize = LE_LONG(loop->cbSize);
440 		loop->ulType = LE_LONG(loop->ulType);
441 		loop->ulStart = LE_LONG(loop->ulStart);
442 		loop->ulLength = LE_LONG(loop->ulLength);
443 		++loop;
444 	}
445 }
446 
Parse_art(DLS_Data * data,RIFF_Chunk * chunk,CONNECTIONLIST ** art_ptr,CONNECTION ** artList_ptr)447 static void Parse_art(DLS_Data *data, RIFF_Chunk *chunk, CONNECTIONLIST **art_ptr, CONNECTION **artList_ptr)
448 {
449 	uint32 i;
450 	CONNECTIONLIST *art = (CONNECTIONLIST *)chunk->data;
451 	CONNECTION *artList;
452 	art->cbSize = LE_LONG(art->cbSize);
453 	art->cConnections = LE_LONG(art->cConnections);
454 	artList = (CONNECTION *)((uint8 *)chunk->data + art->cbSize);
455 	*art_ptr = art;
456 	*artList_ptr = artList;
457 	for ( i = 0; i < art->cConnections; ++i ) {
458 		artList->usSource = LE_SHORT(artList->usSource);
459 		artList->usControl = LE_SHORT(artList->usControl);
460 		artList->usDestination = LE_SHORT(artList->usDestination);
461 		artList->usTransform = LE_SHORT(artList->usTransform);
462 		artList->lScale = LE_LONG(artList->lScale);
463 		++artList;
464 	}
465 }
466 
Parse_lart(DLS_Data * data,RIFF_Chunk * chunk,CONNECTIONLIST ** conn_ptr,CONNECTION ** connList_ptr)467 static void Parse_lart(DLS_Data *data, RIFF_Chunk *chunk, CONNECTIONLIST **conn_ptr, CONNECTION **connList_ptr)
468 {
469 	/* FIXME: This only supports one set of connections */
470 	for ( chunk = chunk->child; chunk; chunk = chunk->next ) {
471 		uint32 magic = (chunk->magic == FOURCC_LIST) ? chunk->subtype : chunk->magic;
472 		switch(magic) {
473 			case FOURCC_ART1:
474 			case FOURCC_ART2:
475 				Parse_art(data, chunk, conn_ptr, connList_ptr);
476 				return;
477 		}
478 	}
479 }
480 
Parse_rgn(DLS_Data * data,RIFF_Chunk * chunk,DLS_Region * region)481 static void Parse_rgn(DLS_Data *data, RIFF_Chunk *chunk, DLS_Region *region)
482 {
483 	for ( chunk = chunk->child; chunk; chunk = chunk->next ) {
484 		uint32 magic = (chunk->magic == FOURCC_LIST) ? chunk->subtype : chunk->magic;
485 		switch(magic) {
486 			case FOURCC_RGNH:
487 				Parse_rgnh(data, chunk, region);
488 				break;
489 			case FOURCC_WLNK:
490 				Parse_wlnk(data, chunk, region);
491 				break;
492 			case FOURCC_WSMP:
493 				Parse_wsmp(data, chunk, &region->wsmp, &region->wsmp_loop);
494 				break;
495 			case FOURCC_LART:
496 			case FOURCC_LAR2:
497 				Parse_lart(data, chunk, &region->art, &region->artList);
498 				break;
499 		}
500 	}
501 }
502 
Parse_lrgn(DLS_Data * data,RIFF_Chunk * chunk,DLS_Instrument * instrument)503 static void Parse_lrgn(DLS_Data *data, RIFF_Chunk *chunk, DLS_Instrument *instrument)
504 {
505 	uint32 region = 0;
506 	for ( chunk = chunk->child; chunk; chunk = chunk->next ) {
507 		uint32 magic = (chunk->magic == FOURCC_LIST) ? chunk->subtype : chunk->magic;
508 		switch(magic) {
509 			case FOURCC_RGN:
510 			case FOURCC_RGN2:
511 				if ( region < instrument->header->cRegions ) {
512 					Parse_rgn(data, chunk, &instrument->regions[region++]);
513 				}
514 				break;
515 		}
516 	}
517 }
518 
Parse_INFO_INS(DLS_Data * data,RIFF_Chunk * chunk,DLS_Instrument * instrument)519 static void Parse_INFO_INS(DLS_Data *data, RIFF_Chunk *chunk, DLS_Instrument *instrument)
520 {
521 	for ( chunk = chunk->child; chunk; chunk = chunk->next ) {
522 		uint32 magic = (chunk->magic == FOURCC_LIST) ? chunk->subtype : chunk->magic;
523 		switch(magic) {
524 			case FOURCC_INAM: /* Name */
525 				instrument->name = (const char*)chunk->data;
526 				break;
527 		}
528 	}
529 }
530 
Parse_ins(DLS_Data * data,RIFF_Chunk * chunk,DLS_Instrument * instrument)531 static void Parse_ins(DLS_Data *data, RIFF_Chunk *chunk, DLS_Instrument *instrument)
532 {
533 	for ( chunk = chunk->child; chunk; chunk = chunk->next ) {
534 		uint32 magic = (chunk->magic == FOURCC_LIST) ? chunk->subtype : chunk->magic;
535 		switch(magic) {
536 			case FOURCC_INSH:
537 				Parse_insh(data, chunk, instrument);
538 				break;
539 			case FOURCC_LRGN:
540 				Parse_lrgn(data, chunk, instrument);
541 				break;
542 			case FOURCC_LART:
543 			case FOURCC_LAR2:
544 				Parse_lart(data, chunk, &instrument->art, &instrument->artList);
545 				break;
546 			case FOURCC_INFO:
547 				Parse_INFO_INS(data, chunk, instrument);
548 				break;
549 		}
550 	}
551 }
552 
Parse_lins(DLS_Data * data,RIFF_Chunk * chunk)553 static void Parse_lins(DLS_Data *data, RIFF_Chunk *chunk)
554 {
555 	uint32 instrument = 0;
556 	for ( chunk = chunk->child; chunk; chunk = chunk->next ) {
557 		uint32 magic = (chunk->magic == FOURCC_LIST) ? chunk->subtype : chunk->magic;
558 		switch(magic) {
559 			case FOURCC_INS:
560 				if ( instrument < data->cInstruments ) {
561 					Parse_ins(data, chunk, &data->instruments[instrument++]);
562 				}
563 				break;
564 		}
565 	}
566 }
567 
Parse_ptbl(DLS_Data * data,RIFF_Chunk * chunk)568 static void Parse_ptbl(DLS_Data *data, RIFF_Chunk *chunk)
569 {
570 	uint32 i;
571 	POOLTABLE *ptbl = (POOLTABLE *)chunk->data;
572 	ptbl->cbSize = LE_LONG(ptbl->cbSize);
573 	ptbl->cCues = LE_LONG(ptbl->cCues);
574 	data->ptbl = ptbl;
575 	data->ptblList = (POOLCUE *)((uint8 *)chunk->data + ptbl->cbSize);
576 	for ( i = 0; i < ptbl->cCues; ++i ) {
577 		data->ptblList[i].ulOffset = LE_LONG(data->ptblList[i].ulOffset);
578 	}
579 	AllocWaveList(data);
580 }
581 
Parse_fmt(DLS_Data * data,RIFF_Chunk * chunk,DLS_Wave * wave)582 static void Parse_fmt(DLS_Data *data, RIFF_Chunk *chunk, DLS_Wave *wave)
583 {
584 	WaveFMT *fmt = (WaveFMT *)chunk->data;
585 	fmt->wFormatTag = LE_SHORT(fmt->wFormatTag);
586 	fmt->wChannels = LE_SHORT(fmt->wChannels);
587 	fmt->dwSamplesPerSec = LE_LONG(fmt->dwSamplesPerSec);
588 	fmt->dwAvgBytesPerSec = LE_LONG(fmt->dwAvgBytesPerSec);
589 	fmt->wBlockAlign = LE_SHORT(fmt->wBlockAlign);
590 	fmt->wBitsPerSample = LE_SHORT(fmt->wBitsPerSample);
591 	wave->format = fmt;
592 }
593 
Parse_data(DLS_Data * data,RIFF_Chunk * chunk,DLS_Wave * wave)594 static void Parse_data(DLS_Data *data, RIFF_Chunk *chunk, DLS_Wave *wave)
595 {
596 	wave->data = chunk->data;
597 	wave->length = chunk->length;
598 }
599 
Parse_wave(DLS_Data * data,RIFF_Chunk * chunk,DLS_Wave * wave)600 static void Parse_wave(DLS_Data *data, RIFF_Chunk *chunk, DLS_Wave *wave)
601 {
602 	for ( chunk = chunk->child; chunk; chunk = chunk->next ) {
603 		uint32 magic = (chunk->magic == FOURCC_LIST) ? chunk->subtype : chunk->magic;
604 		switch(magic) {
605 			case FOURCC_FMT:
606 				Parse_fmt(data, chunk, wave);
607 				break;
608 			case FOURCC_DATA:
609 				Parse_data(data, chunk, wave);
610 				break;
611 			case FOURCC_WSMP:
612 				Parse_wsmp(data, chunk, &wave->wsmp, &wave->wsmp_loop);
613 				break;
614 		}
615 	}
616 }
617 
Parse_wvpl(DLS_Data * data,RIFF_Chunk * chunk)618 static void Parse_wvpl(DLS_Data *data, RIFF_Chunk *chunk)
619 {
620 	uint32 wave = 0;
621 	for ( chunk = chunk->child; chunk; chunk = chunk->next ) {
622 		uint32 magic = (chunk->magic == FOURCC_LIST) ? chunk->subtype : chunk->magic;
623 		switch(magic) {
624 			case FOURCC_wave:
625 				if ( wave < data->ptbl->cCues ) {
626 					Parse_wave(data, chunk, &data->waveList[wave++]);
627 				}
628 				break;
629 		}
630 	}
631 }
632 
Parse_INFO_DLS(DLS_Data * data,RIFF_Chunk * chunk)633 static void Parse_INFO_DLS(DLS_Data *data, RIFF_Chunk *chunk)
634 {
635 	for ( chunk = chunk->child; chunk; chunk = chunk->next ) {
636 		uint32 magic = (chunk->magic == FOURCC_LIST) ? chunk->subtype : chunk->magic;
637 		switch(magic) {
638 			case FOURCC_IARL: /* Archival Location */
639 				break;
640 			case FOURCC_IART: /* Artist */
641 				data->artist = (const char*)chunk->data;
642 				break;
643 			case FOURCC_ICMS: /* Commisioned */
644 				break;
645 			case FOURCC_ICMT: /* Comments */
646 				data->comments = (const char*)chunk->data;
647 				break;
648 			case FOURCC_ICOP: /* Copyright */
649 				data->copyright = (const char*)chunk->data;
650 				break;
651 			case FOURCC_ICRD: /* Creation Date */
652 				break;
653 			case FOURCC_IENG: /* Engineer */
654 				break;
655 			case FOURCC_IGNR: /* Genre */
656 				break;
657 			case FOURCC_IKEY: /* Keywords */
658 				break;
659 			case FOURCC_IMED: /* Medium */
660 				break;
661 			case FOURCC_INAM: /* Name */
662 				data->name = (const char*)chunk->data;
663 				break;
664 			case FOURCC_IPRD: /* Product */
665 				break;
666 			case FOURCC_ISBJ: /* Subject */
667 				break;
668 			case FOURCC_ISFT: /* Software */
669 				break;
670 			case FOURCC_ISRC: /* Source */
671 				break;
672 			case FOURCC_ISRF: /* Source Form */
673 				break;
674 			case FOURCC_ITCH: /* Technician */
675 				break;
676 		}
677 	}
678 }
679 
LoadDLS(FILE * src)680 DLS_Data *LoadDLS(FILE *src)
681 {
682 	RIFF_Chunk *chunk;
683 	DLS_Data *data = (DLS_Data *)malloc(sizeof(*data));
684 	if ( !data ) {
685 		__Sound_SetError(ERR_OUT_OF_MEMORY);
686 		return NULL;
687 	}
688 	memset(data, 0, sizeof(*data));
689 
690 	data->chunk = LoadRIFF(src);
691 	if ( !data->chunk ) {
692 		FreeDLS(data);
693 		return NULL;
694 	}
695 
696 	for ( chunk = data->chunk->child; chunk; chunk = chunk->next ) {
697 		uint32 magic = (chunk->magic == FOURCC_LIST) ? chunk->subtype : chunk->magic;
698 		switch(magic) {
699 			case FOURCC_COLH:
700 				Parse_colh(data, chunk);
701 				break;
702 			case FOURCC_LINS:
703 				Parse_lins(data, chunk);
704 				break;
705 			case FOURCC_PTBL:
706 				Parse_ptbl(data, chunk);
707 				break;
708 			case FOURCC_WVPL:
709 				Parse_wvpl(data, chunk);
710 				break;
711 			case FOURCC_INFO:
712 				Parse_INFO_DLS(data, chunk);
713 				break;
714 		}
715 	}
716 	return data;
717 }
718 
FreeDLS(DLS_Data * data)719 void FreeDLS(DLS_Data *data)
720 {
721 	if ( data->chunk ) {
722 		FreeRIFF(data->chunk);
723 	}
724 	FreeInstruments(data);
725 	FreeWaveList(data);
726 	free(data);
727 	data = NULL;
728 }
729 
730 /*-------------------------------------------------------------------------*/
731 /* * * * * * * * * * * * * * * * * instrum_dls.c * * * * * * * * * * * * * */
732 /*-------------------------------------------------------------------------*/
733 
Timidity_LoadDLS(FILE * src)734 DLS_Data *Timidity_LoadDLS(FILE *src)
735 {
736 	DLS_Data *patches = LoadDLS(src);
737 	//  if (!patches) {
738 	//    SNDDBG(("%s", SDL_GetError()));
739 	//  }
740 	return patches;
741 }
742 
Timidity_FreeDLS(DLS_Data * patches)743 void Timidity_FreeDLS(DLS_Data *patches)
744 {
745 	FreeDLS(patches);
746 }
747 
748 /* convert timecents to sec */
to_msec(int timecent)749 static double to_msec(int timecent)
750 {
751 	if (timecent == 0x80000000 || timecent == 0)
752 		return 0.0;
753 	return 1000.0 * pow(2.0, (double)(timecent / 65536) / 1200.0);
754 }
755 
756 /* convert decipercent to {0..1} */
to_normalized_percent(int decipercent)757 static double to_normalized_percent(int decipercent)
758 {
759 	return ((double)(decipercent / 65536)) / 1000.0;
760 }
761 
762 /* convert from 8bit value to fractional offset (15.15) */
to_offset(int offset)763 static int32 to_offset(int offset)
764 {
765 	return (int32)offset << (7+15);
766 }
767 
768 /* calculate ramp rate in fractional unit;
769 * diff = 8bit, time = msec
770 */
calc_rate(int diff,int sample_rate,double msec)771 static int32 calc_rate(int diff, int sample_rate, double msec)
772 {
773 	double rate;
774 
775 	if(msec < 6)
776 		msec = 6;
777 	if(diff == 0)
778 		diff = 255;
779 	diff <<= (7+15);
780 	rate = ((double)diff / CONTROLS_PER_SECOND) * 1000.0 / msec;
781 	return (int32)rate;
782 }
783 
load_connection(ULONG cConnections,CONNECTION * artList,USHORT destination)784 static int load_connection(ULONG cConnections, CONNECTION *artList, USHORT destination)
785 {
786 	ULONG i;
787 	int value = 0;
788 	for (i = 0; i < cConnections; ++i)
789 	{
790 		CONNECTION *conn = &artList[i];
791 		if(conn->usDestination == destination)
792 		{
793 			// The formula for the destination is:
794 			// usDestination = usDestination + usTransform(usSource * (usControl * lScale))
795 			// Since we are only handling source/control of NONE and identity
796 			// transform, this simplifies to: usDestination = usDestination + lScale
797 			if (conn->usSource == CONN_SRC_NONE &&
798 				conn->usControl == CONN_SRC_NONE &&
799 				conn->usTransform == CONN_TRN_NONE)
800 				value += conn->lScale;
801 		}
802 	}
803 	return value;
804 }
805 
load_region_dls(DLS_Data * patches,Sample * sample,DLS_Instrument * ins,uint32 index)806 static void load_region_dls(DLS_Data *patches, Sample *sample, DLS_Instrument *ins, uint32 index)
807 {
808 	DLS_Region *rgn = &ins->regions[index];
809 	DLS_Wave *wave = &patches->waveList[rgn->wlnk->ulTableIndex];
810 
811 	sample->low_freq = freq_table[rgn->header->RangeKey.usLow];
812 	sample->high_freq = freq_table[rgn->header->RangeKey.usHigh];
813 	sample->root_freq = freq_table[rgn->wsmp->usUnityNote];
814 	sample->low_vel = rgn->header->RangeVelocity.usLow;
815 	sample->high_vel = rgn->header->RangeVelocity.usHigh;
816 
817 	sample->modes = MODES_16BIT;
818 	sample->sample_rate = wave->format->dwSamplesPerSec;
819 	sample->data_length = wave->length / 2;
820 	sample->data = (sample_t *)safe_malloc(wave->length);
821 	memcpy(sample->data, wave->data, wave->length);
822 	if (rgn->wsmp->cSampleLoops)
823 	{
824 		sample->modes |= (MODES_LOOPING|MODES_SUSTAIN);
825 		sample->loop_start = rgn->wsmp_loop->ulStart / 2;
826 		sample->loop_end = sample->loop_start + (rgn->wsmp_loop->ulLength / 2);
827 	}
828 	sample->volume = 1.0f;
829 
830 	if (sample->modes & MODES_SUSTAIN)
831 	{
832 		int value;
833 		double attack, hold, decay, release; int sustain;
834 		CONNECTIONLIST *art = NULL;
835 		CONNECTION *artList = NULL;
836 
837 		if (ins->art && ins->art->cConnections > 0 && ins->artList)
838 		{
839 			art = ins->art;
840 			artList = ins->artList;
841 		}
842 		else
843 		{
844 			art = rgn->art;
845 			artList = rgn->artList;
846 		}
847 
848 		value = load_connection(art->cConnections, artList, CONN_DST_EG1_ATTACKTIME);
849 		attack = to_msec(value);
850 		value = load_connection(art->cConnections, artList, CONN_DST_EG1_HOLDTIME);
851 		hold = to_msec(value);
852 		value = load_connection(art->cConnections, artList, CONN_DST_EG1_DECAYTIME);
853 		decay = to_msec(value);
854 		value = load_connection(art->cConnections, artList, CONN_DST_EG1_RELEASETIME);
855 		release = to_msec(value);
856 		value = load_connection(art->cConnections, artList, CONN_DST_EG1_SUSTAINLEVEL);
857 		sustain = (int)((1.0 - to_normalized_percent(value)) * 250.0);
858 		value = load_connection(art->cConnections, artList, CONN_DST_PAN);
859 		sample->panning = (int)((0.5 + to_normalized_percent(value)) * 127.0);
860 
861 	/*
862 	printf("%d, Rate=%d LV=%d HV=%d Low=%d Hi=%d Root=%d Pan=%d Attack=%f Hold=%f Sustain=%d Decay=%f Release=%f\n", index, sample->sample_rate, rgn->header->RangeVelocity.usLow, rgn->header->RangeVelocity.usHigh, sample->low_freq, sample->high_freq, sample->root_freq, sample->panning, attack, hold, sustain, decay, release);
863 	*/
864 
865 		sample->envelope_offset[ATTACK] = to_offset(255);
866 		sample->envelope_rate[ATTACK] = calc_rate(255, sample->sample_rate, attack);
867 
868 		sample->envelope_offset[HOLD] = to_offset(250);
869 		sample->envelope_rate[HOLD] = calc_rate(5, sample->sample_rate, hold);
870 
871 		sample->envelope_offset[DECAY] = to_offset(sustain);
872 		sample->envelope_rate[DECAY] = calc_rate(255 - sustain, sample->sample_rate, decay);
873 
874 		sample->envelope_offset[RELEASE] = to_offset(0);
875 		sample->envelope_rate[RELEASE] = calc_rate(5 + sustain, sample->sample_rate, release);
876 
877 		sample->envelope_offset[RELEASEB] = to_offset(0);
878 		sample->envelope_rate[RELEASEB] = to_offset(1);
879 
880 		sample->envelope_offset[RELEASEC] = to_offset(0);
881 		sample->envelope_rate[RELEASEC] = to_offset(1);
882 
883 		sample->modes |= MODES_ENVELOPE;
884 	}
885 
886 	sample->data_length <<= FRACTION_BITS;
887 	sample->loop_start <<= FRACTION_BITS;
888 	sample->loop_end <<= FRACTION_BITS;
889 }
890 
load_instrument_dls(MidiSong * song,int drum,int bank,int instrument)891 Instrument* load_instrument_dls(MidiSong *song, int drum, int bank, int instrument)
892 {
893 	Instrument *inst;
894 	uint32 i;
895 	DLS_Instrument *dls_ins;
896 
897 	if (!song->patches)
898 		return(NULL);
899 
900 	if (!drum)
901 	{
902 		for (i = 0; i < song->patches->cInstruments; ++i)
903 		{
904 			dls_ins = &song->patches->instruments[i];
905 			if (!(dls_ins->header->Locale.ulBank & 0x80000000) &&
906 				((dls_ins->header->Locale.ulBank >> 8) & 0xFF) == bank &&
907 				dls_ins->header->Locale.ulInstrument == instrument)
908 				break;
909 		}
910 		if (i == song->patches->cInstruments && !bank)
911 		{
912 			for (i = 0; i < song->patches->cInstruments; ++i)
913 			{
914 				dls_ins = &song->patches->instruments[i];
915 				if (!(dls_ins->header->Locale.ulBank & 0x80000000) &&
916 					dls_ins->header->Locale.ulInstrument == instrument)
917 					break;
918 			}
919 		}
920 		if (i == song->patches->cInstruments)
921 		{
922 			ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Couldn't find melodic instrument %d in bank %d\n", instrument, bank);
923 			return(NULL);
924 		}
925 
926 		inst = (Instrument *)safe_malloc(sizeof(*inst));
927 		inst->type = INST_DLS;
928 		inst->samples = dls_ins->header->cRegions;
929 		inst->sample = (Sample *)safe_malloc(inst->samples * sizeof(*inst->sample));
930 		memset(inst->sample, 0, inst->samples * sizeof(*inst->sample));
931 		for (i = 0; i < dls_ins->header->cRegions; ++i)
932 		{
933 			load_region_dls(song->patches, &inst->sample[i], dls_ins, i);
934 		}
935 	}
936 	else
937 	{
938 		for (i = 0; i < song->patches->cInstruments; ++i)
939 		{
940 			dls_ins = &song->patches->instruments[i];
941 			if ((dls_ins->header->Locale.ulBank & 0x80000000) &&
942 				dls_ins->header->Locale.ulInstrument == bank)
943 				break;
944 		}
945 		if (i == song->patches->cInstruments && !bank)
946 		{
947 			for (i = 0; i < song->patches->cInstruments; ++i)
948 			{
949 				dls_ins = &song->patches->instruments[i];
950 				if ((dls_ins->header->Locale.ulBank & 0x80000000) &&
951 					dls_ins->header->Locale.ulInstrument == 0)
952 					break;
953 			}
954 		}
955 		if (i == song->patches->cInstruments)
956 		{
957 			ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Couldn't find drum instrument %d\n", bank);
958 			return(NULL);
959 		}
960 
961 		int drum_reg = -1;
962 		for (i = 0; i < dls_ins->header->cRegions; i++)
963 		{
964 			if (dls_ins->regions[i].header->RangeKey.usLow == instrument)
965 			{
966 				drum_reg = i;
967 				break;
968 			}
969 		}
970 		if (drum_reg == -1)
971 		{
972 			ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Couldn't find drum note %d\n", instrument);
973 			return(NULL);
974 		}
975 
976 		inst = (Instrument *)safe_malloc(sizeof(*inst));
977 		inst->type = INST_DLS;
978 		inst->samples = 1;
979 		inst->sample = (Sample *)safe_malloc(inst->samples * sizeof(*inst->sample));
980 		memset(inst->sample, 0, inst->samples * sizeof(*inst->sample));
981 		load_region_dls(song->patches, &inst->sample[0], dls_ins, drum_reg);
982 	}
983 
984 	return inst;
985 }
986 
987 }
988