comparison decoders/timidity/instrum_dls.c @ 455:cbc2a4ffeeec

* Added support for loading DLS format instruments: Timidity_LoadDLS(), Timidity_FreeDLS(), Timidity_LoadDLSSong() * Added Timidity_Init_NoConfig()
author hercules
date Fri, 26 Sep 2003 20:51:58 +0000
parents
children 69c8ba97f4bd
comparison
equal deleted inserted replaced
454:6bd7ca7d218b 455:cbc2a4ffeeec
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 "SDL.h"
28 #include "SDL_endian.h"
29 #include "SDL_rwops.h"
30
31 #include "SDL_sound.h"
32
33 #define __SDL_SOUND_INTERNAL__
34 #include "SDL_sound_internal.h"
35
36 #include "timidity.h"
37 #include "options.h"
38 #include "instrum.h"
39 #include "tables.h"
40 #include "common.h"
41
42 /*-------------------------------------------------------------------------*/
43 /* * * * * * * * * * * * * * * * * load_riff.h * * * * * * * * * * * * * * */
44 /*-------------------------------------------------------------------------*/
45 typedef struct _RIFF_Chunk {
46 Uint32 magic;
47 Uint32 length;
48 Uint32 subtype;
49 Uint8 *data;
50 struct _RIFF_Chunk *child;
51 struct _RIFF_Chunk *next;
52 } RIFF_Chunk;
53
54 extern DECLSPEC RIFF_Chunk* SDLCALL LoadRIFF(SDL_RWops *src);
55 extern DECLSPEC void SDLCALL FreeRIFF(RIFF_Chunk *chunk);
56 extern DECLSPEC void SDLCALL PrintRIFF(RIFF_Chunk *chunk, int level);
57 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
58
59 /*-------------------------------------------------------------------------*/
60 /* * * * * * * * * * * * * * * * * load_riff.c * * * * * * * * * * * * * * */
61 /*-------------------------------------------------------------------------*/
62 #define RIFF 0x46464952 /* "RIFF" */
63 #define LIST 0x5453494c /* "LIST" */
64
65 static RIFF_Chunk *AllocRIFFChunk()
66 {
67 RIFF_Chunk *chunk = (RIFF_Chunk *)malloc(sizeof(*chunk));
68 if ( !chunk ) {
69 SDL_Error(SDL_ENOMEM);
70 return NULL;
71 }
72 memset(chunk, 0, sizeof(*chunk));
73 return chunk;
74 }
75
76 static void FreeRIFFChunk(RIFF_Chunk *chunk)
77 {
78 if ( chunk->child ) {
79 FreeRIFFChunk(chunk->child);
80 }
81 while ( chunk->next ) {
82 RIFF_Chunk *freeable = chunk->next;
83 chunk->next = freeable->next;
84 FreeRIFFChunk(freeable);
85 }
86 free(chunk);
87 }
88
89 static int ChunkHasSubType(Uint32 magic)
90 {
91 static Uint32 chunk_list[] = {
92 RIFF, LIST
93 };
94 int i;
95 for ( i = 0; i < SDL_TABLESIZE(chunk_list); ++i ) {
96 if ( magic == chunk_list[i] ) {
97 return 1;
98 }
99 }
100 return 0;
101 }
102
103 static int ChunkHasSubChunks(Uint32 magic)
104 {
105 static Uint32 chunk_list[] = {
106 RIFF, LIST
107 };
108 int i;
109 for ( i = 0; i < SDL_TABLESIZE(chunk_list); ++i ) {
110 if ( magic == chunk_list[i] ) {
111 return 1;
112 }
113 }
114 return 0;
115 }
116
117 static void LoadSubChunks(RIFF_Chunk *chunk, Uint8 *data, Uint32 left)
118 {
119 Uint8 *subchunkData;
120 Uint32 subchunkDataLen;
121
122 while ( left > 8 ) {
123 RIFF_Chunk *child = AllocRIFFChunk();
124 RIFF_Chunk *next, *prev = NULL;
125 for ( next = chunk->child; next; next = next->next ) {
126 prev = next;
127 }
128 if ( prev ) {
129 prev->next = child;
130 } else {
131 chunk->child = child;
132 }
133
134 child->magic = (data[0] << 0) |
135 (data[1] << 8) |
136 (data[2] << 16) |
137 (data[3] << 24);
138 data += 4;
139 left -= 4;
140 child->length = (data[0] << 0) |
141 (data[1] << 8) |
142 (data[2] << 16) |
143 (data[3] << 24);
144 data += 4;
145 left -= 4;
146 child->data = data;
147
148 if ( child->length > left ) {
149 child->length = left;
150 }
151
152 subchunkData = child->data;
153 subchunkDataLen = child->length;
154 if ( ChunkHasSubType(child->magic) && subchunkDataLen >= 4 ) {
155 child->subtype = (subchunkData[0] << 0) |
156 (subchunkData[1] << 8) |
157 (subchunkData[2] << 16) |
158 (subchunkData[3] << 24);
159 subchunkData += 4;
160 subchunkDataLen -= 4;
161 }
162 if ( ChunkHasSubChunks(child->magic) ) {
163 LoadSubChunks(child, subchunkData, subchunkDataLen);
164 }
165
166 data += child->length;
167 left -= child->length;
168 }
169 }
170
171 RIFF_Chunk *LoadRIFF(SDL_RWops *src)
172 {
173 RIFF_Chunk *chunk;
174 Uint8 *subchunkData;
175 Uint32 subchunkDataLen;
176
177 /* Allocate the chunk structure */
178 chunk = AllocRIFFChunk();
179
180 /* Make sure the file is in RIFF format */
181 chunk->magic = SDL_ReadLE32(src);
182 chunk->length = SDL_ReadLE32(src);
183 if ( chunk->magic != RIFF ) {
184 SDL_SetError("Not a RIFF file");
185 FreeRIFFChunk(chunk);
186 return NULL;
187 }
188 chunk->data = (Uint8 *)malloc(chunk->length);
189 if ( chunk->data == NULL ) {
190 SDL_Error(SDL_ENOMEM);
191 FreeRIFFChunk(chunk);
192 return NULL;
193 }
194 if ( SDL_RWread(src, chunk->data, chunk->length, 1) != 1 ) {
195 SDL_Error(SDL_EFREAD);
196 FreeRIFF(chunk);
197 return NULL;
198 }
199 subchunkData = chunk->data;
200 subchunkDataLen = chunk->length;
201 if ( ChunkHasSubType(chunk->magic) && subchunkDataLen >= 4 ) {
202 chunk->subtype = (subchunkData[0] << 0) |
203 (subchunkData[1] << 8) |
204 (subchunkData[2] << 16) |
205 (subchunkData[3] << 24);
206 subchunkData += 4;
207 subchunkDataLen -= 4;
208 }
209 if ( ChunkHasSubChunks(chunk->magic) ) {
210 LoadSubChunks(chunk, subchunkData, subchunkDataLen);
211 }
212 return chunk;
213 }
214
215 void FreeRIFF(RIFF_Chunk *chunk)
216 {
217 free(chunk->data);
218 FreeRIFFChunk(chunk);
219 }
220
221 void PrintRIFF(RIFF_Chunk *chunk, int level)
222 {
223 static char prefix[128];
224
225 if ( level == sizeof(prefix)-1 ) {
226 return;
227 }
228 if ( level > 0 ) {
229 prefix[(level-1)*2] = ' ';
230 prefix[(level-1)*2+1] = ' ';
231 }
232 prefix[level*2] = '\0';
233 printf("%sChunk: %c%c%c%c (%d bytes)", prefix,
234 ((chunk->magic >> 0) & 0xFF),
235 ((chunk->magic >> 8) & 0xFF),
236 ((chunk->magic >> 16) & 0xFF),
237 ((chunk->magic >> 24) & 0xFF), chunk->length);
238 if ( chunk->subtype ) {
239 printf(" subtype: %c%c%c%c",
240 ((chunk->subtype >> 0) & 0xFF),
241 ((chunk->subtype >> 8) & 0xFF),
242 ((chunk->subtype >> 16) & 0xFF),
243 ((chunk->subtype >> 24) & 0xFF));
244 }
245 printf("\n");
246 if ( chunk->child ) {
247 printf("%s{\n", prefix);
248 PrintRIFF(chunk->child, level + 1);
249 printf("%s}\n", prefix);
250 }
251 if ( chunk->next ) {
252 PrintRIFF(chunk->next, level);
253 }
254 if ( level > 0 ) {
255 prefix[(level-1)*2] = '\0';
256 }
257 }
258
259 #ifdef TEST_MAIN_RIFF
260
261 main(int argc, char *argv[])
262 {
263 int i;
264 for ( i = 1; i < argc; ++i ) {
265 RIFF_Chunk *chunk;
266 SDL_RWops *src = SDL_RWFromFile(argv[i], "rb");
267 if ( !src ) {
268 fprintf(stderr, "Couldn't open %s: %s", argv[i], SDL_GetError());
269 continue;
270 }
271 chunk = LoadRIFF(src);
272 if ( chunk ) {
273 PrintRIFF(chunk, 0);
274 FreeRIFF(chunk);
275 } else {
276 fprintf(stderr, "Couldn't load %s: %s\n", argv[i], SDL_GetError());
277 }
278 SDL_RWclose(src);
279 }
280 }
281
282 #endif // TEST_MAIN
283 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
284
285 /*-------------------------------------------------------------------------*/
286 /* * * * * * * * * * * * * * * * * load_dls.h * * * * * * * * * * * * * * */
287 /*-------------------------------------------------------------------------*/
288 /* This code is based on the DLS spec version 1.1, available at:
289 http://www.midi.org/about-midi/dls/dlsspec.shtml
290 */
291
292 /* Some typedefs so the public dls headers don't need to be modified */
293 #define FAR
294 typedef Uint8 BYTE;
295 typedef Sint16 SHORT;
296 typedef Uint16 USHORT;
297 typedef Uint16 WORD;
298 typedef Sint32 LONG;
299 typedef Uint32 ULONG;
300 typedef Uint32 DWORD;
301 #define mmioFOURCC(A, B, C, D) \
302 (((A) << 0) | ((B) << 8) | ((C) << 16) | ((D) << 24))
303 #define DEFINE_GUID(A, B, C, E, F, G, H, I, J, K, L, M)
304
305 #include "dls1.h"
306 #include "dls2.h"
307
308 typedef struct _WaveFMT {
309 WORD wFormatTag;
310 WORD wChannels;
311 DWORD dwSamplesPerSec;
312 DWORD dwAvgBytesPerSec;
313 WORD wBlockAlign;
314 WORD wBitsPerSample;
315 } WaveFMT;
316
317 typedef struct _DLS_Wave {
318 WaveFMT *format;
319 Uint8 *data;
320 Uint32 length;
321 WSMPL *wsmp;
322 WLOOP *wsmp_loop;
323 } DLS_Wave;
324
325 typedef struct _DLS_Region {
326 RGNHEADER *header;
327 WAVELINK *wlnk;
328 WSMPL *wsmp;
329 WLOOP *wsmp_loop;
330 CONNECTIONLIST *art;
331 CONNECTION *artList;
332 } DLS_Region;
333
334 typedef struct _DLS_Instrument {
335 const char *name;
336 INSTHEADER *header;
337 DLS_Region *regions;
338 CONNECTIONLIST *art;
339 CONNECTION *artList;
340 } DLS_Instrument;
341
342 typedef struct _DLS_Data {
343 struct _RIFF_Chunk *chunk;
344
345 Uint32 cInstruments;
346 DLS_Instrument *instruments;
347
348 POOLTABLE *ptbl;
349 POOLCUE *ptblList;
350 DLS_Wave *waveList;
351
352 const char *name;
353 const char *artist;
354 const char *copyright;
355 const char *comments;
356 } DLS_Data;
357
358 extern DECLSPEC DLS_Data* SDLCALL LoadDLS(SDL_RWops *src);
359 extern DECLSPEC void SDLCALL FreeDLS(DLS_Data *chunk);
360 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
361
362 /*-------------------------------------------------------------------------*/
363 /* * * * * * * * * * * * * * * * * load_dls.c * * * * * * * * * * * * * * */
364 /*-------------------------------------------------------------------------*/
365
366 #define FOURCC_LIST 0x5453494c /* "LIST" */
367 #define FOURCC_FMT 0x20746D66 /* "fmt " */
368 #define FOURCC_DATA 0x61746164 /* "data" */
369 #define FOURCC_INFO mmioFOURCC('I','N','F','O')
370 #define FOURCC_IARL mmioFOURCC('I','A','R','L')
371 #define FOURCC_IART mmioFOURCC('I','A','R','T')
372 #define FOURCC_ICMS mmioFOURCC('I','C','M','S')
373 #define FOURCC_ICMT mmioFOURCC('I','C','M','T')
374 #define FOURCC_ICOP mmioFOURCC('I','C','O','P')
375 #define FOURCC_ICRD mmioFOURCC('I','C','R','D')
376 #define FOURCC_IENG mmioFOURCC('I','E','N','G')
377 #define FOURCC_IGNR mmioFOURCC('I','G','N','R')
378 #define FOURCC_IKEY mmioFOURCC('I','K','E','Y')
379 #define FOURCC_IMED mmioFOURCC('I','M','E','D')
380 #define FOURCC_INAM mmioFOURCC('I','N','A','M')
381 #define FOURCC_IPRD mmioFOURCC('I','P','R','D')
382 #define FOURCC_ISBJ mmioFOURCC('I','S','B','J')
383 #define FOURCC_ISFT mmioFOURCC('I','S','F','T')
384 #define FOURCC_ISRC mmioFOURCC('I','S','R','C')
385 #define FOURCC_ISRF mmioFOURCC('I','S','R','F')
386 #define FOURCC_ITCH mmioFOURCC('I','T','C','H')
387
388
389 static void FreeRegions(DLS_Instrument *instrument)
390 {
391 if ( instrument->regions ) {
392 free(instrument->regions);
393 }
394 }
395
396 static void AllocRegions(DLS_Instrument *instrument)
397 {
398 int datalen = (instrument->header->cRegions * sizeof(DLS_Region));
399 FreeRegions(instrument);
400 instrument->regions = (DLS_Region *)malloc(datalen);
401 if ( instrument->regions ) {
402 memset(instrument->regions, 0, datalen);
403 }
404 }
405
406 static void FreeInstruments(DLS_Data *data)
407 {
408 if ( data->instruments ) {
409 Uint32 i;
410 for ( i = 0; i < data->cInstruments; ++i ) {
411 FreeRegions(&data->instruments[i]);
412 }
413 free(data->instruments);
414 }
415 }
416
417 static void AllocInstruments(DLS_Data *data)
418 {
419 int datalen = (data->cInstruments * sizeof(DLS_Instrument));
420 FreeInstruments(data);
421 data->instruments = (DLS_Instrument *)malloc(datalen);
422 if ( data->instruments ) {
423 memset(data->instruments, 0, datalen);
424 }
425 }
426
427 static void FreeWaveList(DLS_Data *data)
428 {
429 if ( data->waveList ) {
430 free(data->waveList);
431 }
432 }
433
434 static void AllocWaveList(DLS_Data *data)
435 {
436 int datalen = (data->ptbl->cCues * sizeof(DLS_Wave));
437 FreeWaveList(data);
438 data->waveList = (DLS_Wave *)malloc(datalen);
439 if ( data->waveList ) {
440 memset(data->waveList, 0, datalen);
441 }
442 }
443
444 static void Parse_colh(DLS_Data *data, RIFF_Chunk *chunk)
445 {
446 data->cInstruments = SDL_SwapLE32(*(Uint32 *)chunk->data);
447 AllocInstruments(data);
448 }
449
450 static void Parse_insh(DLS_Data *data, RIFF_Chunk *chunk, DLS_Instrument *instrument)
451 {
452 INSTHEADER *header = (INSTHEADER *)chunk->data;
453 header->cRegions = SDL_SwapLE32(header->cRegions);
454 header->Locale.ulBank = SDL_SwapLE32(header->Locale.ulBank);
455 header->Locale.ulInstrument = SDL_SwapLE32(header->Locale.ulInstrument);
456 instrument->header = header;
457 AllocRegions(instrument);
458 }
459
460 static void Parse_rgnh(DLS_Data *data, RIFF_Chunk *chunk, DLS_Region *region)
461 {
462 RGNHEADER *header = (RGNHEADER *)chunk->data;
463 header->RangeKey.usLow = SDL_SwapLE16(header->RangeKey.usLow);
464 header->RangeKey.usHigh = SDL_SwapLE16(header->RangeKey.usHigh);
465 header->RangeVelocity.usLow = SDL_SwapLE16(header->RangeVelocity.usLow);
466 header->RangeVelocity.usHigh = SDL_SwapLE16(header->RangeVelocity.usHigh);
467 header->fusOptions = SDL_SwapLE16(header->fusOptions);
468 header->usKeyGroup = SDL_SwapLE16(header->usKeyGroup);
469 region->header = header;
470 }
471
472 static void Parse_wlnk(DLS_Data *data, RIFF_Chunk *chunk, DLS_Region *region)
473 {
474 WAVELINK *wlnk = (WAVELINK *)chunk->data;
475 wlnk->fusOptions = SDL_SwapLE16(wlnk->fusOptions);
476 wlnk->usPhaseGroup = SDL_SwapLE16(wlnk->usPhaseGroup);
477 wlnk->ulChannel = SDL_SwapLE16(wlnk->ulChannel);
478 wlnk->ulTableIndex = SDL_SwapLE16(wlnk->ulTableIndex);
479 region->wlnk = wlnk;
480 }
481
482 static void Parse_wsmp(DLS_Data *data, RIFF_Chunk *chunk, WSMPL **wsmp_ptr, WLOOP **wsmp_loop_ptr)
483 {
484 Uint32 i;
485 WSMPL *wsmp = (WSMPL *)chunk->data;
486 WLOOP *loop;
487 wsmp->cbSize = SDL_SwapLE32(wsmp->cbSize);
488 wsmp->usUnityNote = SDL_SwapLE16(wsmp->usUnityNote);
489 wsmp->sFineTune = SDL_SwapLE16(wsmp->sFineTune);
490 wsmp->lAttenuation = SDL_SwapLE32(wsmp->lAttenuation);
491 wsmp->fulOptions = SDL_SwapLE32(wsmp->fulOptions);
492 wsmp->cSampleLoops = SDL_SwapLE32(wsmp->cSampleLoops);
493 loop = (WLOOP *)((Uint8 *)chunk->data + wsmp->cbSize);
494 *wsmp_ptr = wsmp;
495 *wsmp_loop_ptr = loop;
496 for ( i = 0; i < wsmp->cSampleLoops; ++i ) {
497 loop->cbSize = SDL_SwapLE32(loop->cbSize);
498 loop->ulType = SDL_SwapLE32(loop->ulType);
499 loop->ulStart = SDL_SwapLE32(loop->ulStart);
500 loop->ulLength = SDL_SwapLE32(loop->ulLength);
501 ++loop;
502 }
503 }
504
505 static void Parse_art(DLS_Data *data, RIFF_Chunk *chunk, CONNECTIONLIST **art_ptr, CONNECTION **artList_ptr)
506 {
507 Uint32 i;
508 CONNECTIONLIST *art = (CONNECTIONLIST *)chunk->data;
509 CONNECTION *artList;
510 art->cbSize = SDL_SwapLE32(art->cbSize);
511 art->cConnections = SDL_SwapLE32(art->cConnections);
512 artList = (CONNECTION *)((Uint8 *)chunk->data + art->cbSize);
513 *art_ptr = art;
514 *artList_ptr = artList;
515 for ( i = 0; i < art->cConnections; ++i ) {
516 artList->usSource = SDL_SwapLE16(artList->usSource);
517 artList->usControl = SDL_SwapLE16(artList->usControl);
518 artList->usDestination = SDL_SwapLE16(artList->usDestination);
519 artList->usTransform = SDL_SwapLE16(artList->usTransform);
520 artList->lScale = SDL_SwapLE32(artList->lScale);
521 ++artList;
522 }
523 }
524
525 static void Parse_lart(DLS_Data *data, RIFF_Chunk *chunk, CONNECTIONLIST **conn_ptr, CONNECTION **connList_ptr)
526 {
527 /* FIXME: This only supports one set of connections */
528 for ( chunk = chunk->child; chunk; chunk = chunk->next ) {
529 Uint32 magic = (chunk->magic == FOURCC_LIST) ? chunk->subtype : chunk->magic;
530 switch(magic) {
531 case FOURCC_ART1:
532 case FOURCC_ART2:
533 Parse_art(data, chunk, conn_ptr, connList_ptr);
534 return;
535 }
536 }
537 }
538
539 static void Parse_rgn(DLS_Data *data, RIFF_Chunk *chunk, DLS_Region *region)
540 {
541 for ( chunk = chunk->child; chunk; chunk = chunk->next ) {
542 Uint32 magic = (chunk->magic == FOURCC_LIST) ? chunk->subtype : chunk->magic;
543 switch(magic) {
544 case FOURCC_RGNH:
545 Parse_rgnh(data, chunk, region);
546 break;
547 case FOURCC_WLNK:
548 Parse_wlnk(data, chunk, region);
549 break;
550 case FOURCC_WSMP:
551 Parse_wsmp(data, chunk, &region->wsmp, &region->wsmp_loop);
552 break;
553 case FOURCC_LART:
554 case FOURCC_LAR2:
555 Parse_lart(data, chunk, &region->art, &region->artList);
556 break;
557 }
558 }
559 }
560
561 static void Parse_lrgn(DLS_Data *data, RIFF_Chunk *chunk, DLS_Instrument *instrument)
562 {
563 Uint32 region = 0;
564 for ( chunk = chunk->child; chunk; chunk = chunk->next ) {
565 Uint32 magic = (chunk->magic == FOURCC_LIST) ? chunk->subtype : chunk->magic;
566 switch(magic) {
567 case FOURCC_RGN:
568 case FOURCC_RGN2:
569 if ( region < instrument->header->cRegions ) {
570 Parse_rgn(data, chunk, &instrument->regions[region++]);
571 }
572 break;
573 }
574 }
575 }
576
577 static void Parse_INFO_INS(DLS_Data *data, RIFF_Chunk *chunk, DLS_Instrument *instrument)
578 {
579 for ( chunk = chunk->child; chunk; chunk = chunk->next ) {
580 Uint32 magic = (chunk->magic == FOURCC_LIST) ? chunk->subtype : chunk->magic;
581 switch(magic) {
582 case FOURCC_INAM: /* Name */
583 instrument->name = chunk->data;
584 break;
585 }
586 }
587 }
588
589 static void Parse_ins(DLS_Data *data, RIFF_Chunk *chunk, DLS_Instrument *instrument)
590 {
591 for ( chunk = chunk->child; chunk; chunk = chunk->next ) {
592 Uint32 magic = (chunk->magic == FOURCC_LIST) ? chunk->subtype : chunk->magic;
593 switch(magic) {
594 case FOURCC_INSH:
595 Parse_insh(data, chunk, instrument);
596 break;
597 case FOURCC_LRGN:
598 Parse_lrgn(data, chunk, instrument);
599 break;
600 case FOURCC_LART:
601 case FOURCC_LAR2:
602 Parse_lart(data, chunk, &instrument->art, &instrument->artList);
603 break;
604 case FOURCC_INFO:
605 Parse_INFO_INS(data, chunk, instrument);
606 break;
607 }
608 }
609 }
610
611 static void Parse_lins(DLS_Data *data, RIFF_Chunk *chunk)
612 {
613 Uint32 instrument = 0;
614 for ( chunk = chunk->child; chunk; chunk = chunk->next ) {
615 Uint32 magic = (chunk->magic == FOURCC_LIST) ? chunk->subtype : chunk->magic;
616 switch(magic) {
617 case FOURCC_INS:
618 if ( instrument < data->cInstruments ) {
619 Parse_ins(data, chunk, &data->instruments[instrument++]);
620 }
621 break;
622 }
623 }
624 }
625
626 static void Parse_ptbl(DLS_Data *data, RIFF_Chunk *chunk)
627 {
628 Uint32 i;
629 POOLTABLE *ptbl = (POOLTABLE *)chunk->data;
630 ptbl->cbSize = SDL_SwapLE32(ptbl->cbSize);
631 ptbl->cCues = SDL_SwapLE32(ptbl->cCues);
632 data->ptbl = ptbl;
633 data->ptblList = (POOLCUE *)((Uint8 *)chunk->data + ptbl->cbSize);
634 for ( i = 0; i < ptbl->cCues; ++i ) {
635 data->ptblList[i].ulOffset = SDL_SwapLE32(data->ptblList[i].ulOffset);
636 }
637 AllocWaveList(data);
638 }
639
640 static void Parse_fmt(DLS_Data *data, RIFF_Chunk *chunk, DLS_Wave *wave)
641 {
642 WaveFMT *fmt = (WaveFMT *)chunk->data;
643 fmt->wFormatTag = SDL_SwapLE16(fmt->wFormatTag);
644 fmt->wChannels = SDL_SwapLE16(fmt->wChannels);
645 fmt->dwSamplesPerSec = SDL_SwapLE32(fmt->dwSamplesPerSec);
646 fmt->dwAvgBytesPerSec = SDL_SwapLE32(fmt->dwAvgBytesPerSec);
647 fmt->wBlockAlign = SDL_SwapLE16(fmt->wBlockAlign);
648 fmt->wBitsPerSample = SDL_SwapLE16(fmt->wBitsPerSample);
649 wave->format = fmt;
650 }
651
652 static void Parse_data(DLS_Data *data, RIFF_Chunk *chunk, DLS_Wave *wave)
653 {
654 wave->data = chunk->data;
655 wave->length = chunk->length;
656 }
657
658 static void Parse_wave(DLS_Data *data, RIFF_Chunk *chunk, DLS_Wave *wave)
659 {
660 for ( chunk = chunk->child; chunk; chunk = chunk->next ) {
661 Uint32 magic = (chunk->magic == FOURCC_LIST) ? chunk->subtype : chunk->magic;
662 switch(magic) {
663 case FOURCC_FMT:
664 Parse_fmt(data, chunk, wave);
665 break;
666 case FOURCC_DATA:
667 Parse_data(data, chunk, wave);
668 break;
669 case FOURCC_WSMP:
670 Parse_wsmp(data, chunk, &wave->wsmp, &wave->wsmp_loop);
671 break;
672 }
673 }
674 }
675
676 static void Parse_wvpl(DLS_Data *data, RIFF_Chunk *chunk)
677 {
678 Uint32 wave = 0;
679 for ( chunk = chunk->child; chunk; chunk = chunk->next ) {
680 Uint32 magic = (chunk->magic == FOURCC_LIST) ? chunk->subtype : chunk->magic;
681 switch(magic) {
682 case FOURCC_wave:
683 if ( wave < data->ptbl->cCues ) {
684 Parse_wave(data, chunk, &data->waveList[wave++]);
685 }
686 break;
687 }
688 }
689 }
690
691 static void Parse_INFO_DLS(DLS_Data *data, RIFF_Chunk *chunk)
692 {
693 for ( chunk = chunk->child; chunk; chunk = chunk->next ) {
694 Uint32 magic = (chunk->magic == FOURCC_LIST) ? chunk->subtype : chunk->magic;
695 switch(magic) {
696 case FOURCC_IARL: /* Archival Location */
697 break;
698 case FOURCC_IART: /* Artist */
699 data->artist = chunk->data;
700 break;
701 case FOURCC_ICMS: /* Commisioned */
702 break;
703 case FOURCC_ICMT: /* Comments */
704 data->comments = chunk->data;
705 break;
706 case FOURCC_ICOP: /* Copyright */
707 data->copyright = chunk->data;
708 break;
709 case FOURCC_ICRD: /* Creation Date */
710 break;
711 case FOURCC_IENG: /* Engineer */
712 break;
713 case FOURCC_IGNR: /* Genre */
714 break;
715 case FOURCC_IKEY: /* Keywords */
716 break;
717 case FOURCC_IMED: /* Medium */
718 break;
719 case FOURCC_INAM: /* Name */
720 data->name = chunk->data;
721 break;
722 case FOURCC_IPRD: /* Product */
723 break;
724 case FOURCC_ISBJ: /* Subject */
725 break;
726 case FOURCC_ISFT: /* Software */
727 break;
728 case FOURCC_ISRC: /* Source */
729 break;
730 case FOURCC_ISRF: /* Source Form */
731 break;
732 case FOURCC_ITCH: /* Technician */
733 break;
734 }
735 }
736 }
737
738 DLS_Data *LoadDLS(SDL_RWops *src)
739 {
740 RIFF_Chunk *chunk;
741 DLS_Data *data = (DLS_Data *)malloc(sizeof(*data));
742 if ( !data ) {
743 SDL_Error(SDL_ENOMEM);
744 return NULL;
745 }
746 memset(data, 0, sizeof(*data));
747
748 data->chunk = LoadRIFF(src);
749 if ( !data->chunk ) {
750 FreeDLS(data);
751 return NULL;
752 }
753
754 for ( chunk = data->chunk->child; chunk; chunk = chunk->next ) {
755 Uint32 magic = (chunk->magic == FOURCC_LIST) ? chunk->subtype : chunk->magic;
756 switch(magic) {
757 case FOURCC_COLH:
758 Parse_colh(data, chunk);
759 break;
760 case FOURCC_LINS:
761 Parse_lins(data, chunk);
762 break;
763 case FOURCC_PTBL:
764 Parse_ptbl(data, chunk);
765 break;
766 case FOURCC_WVPL:
767 Parse_wvpl(data, chunk);
768 break;
769 case FOURCC_INFO:
770 Parse_INFO_DLS(data, chunk);
771 break;
772 }
773 }
774 return data;
775 }
776
777 void FreeDLS(DLS_Data *data)
778 {
779 if ( data->chunk ) {
780 FreeRIFF(data->chunk);
781 }
782 FreeInstruments(data);
783 FreeWaveList(data);
784 free(data);
785 }
786
787 static const char *SourceToString(USHORT usSource)
788 {
789 switch(usSource) {
790 case CONN_SRC_NONE:
791 return "NONE";
792 case CONN_SRC_LFO:
793 return "LFO";
794 case CONN_SRC_KEYONVELOCITY:
795 return "KEYONVELOCITY";
796 case CONN_SRC_KEYNUMBER:
797 return "KEYNUMBER";
798 case CONN_SRC_EG1:
799 return "EG1";
800 case CONN_SRC_EG2:
801 return "EG2";
802 case CONN_SRC_PITCHWHEEL:
803 return "PITCHWHEEL";
804 case CONN_SRC_CC1:
805 return "CC1";
806 case CONN_SRC_CC7:
807 return "CC7";
808 case CONN_SRC_CC10:
809 return "CC10";
810 case CONN_SRC_CC11:
811 return "CC11";
812 case CONN_SRC_POLYPRESSURE:
813 return "POLYPRESSURE";
814 case CONN_SRC_CHANNELPRESSURE:
815 return "CHANNELPRESSURE";
816 case CONN_SRC_VIBRATO:
817 return "VIBRATO";
818 case CONN_SRC_MONOPRESSURE:
819 return "MONOPRESSURE";
820 case CONN_SRC_CC91:
821 return "CC91";
822 case CONN_SRC_CC93:
823 return "CC93";
824 default:
825 return "UNKNOWN";
826 }
827 }
828
829 static const char *TransformToString(USHORT usTransform)
830 {
831 switch (usTransform) {
832 case CONN_TRN_NONE:
833 return "NONE";
834 case CONN_TRN_CONCAVE:
835 return "CONCAVE";
836 case CONN_TRN_CONVEX:
837 return "CONVEX";
838 case CONN_TRN_SWITCH:
839 return "SWITCH";
840 default:
841 return "UNKNOWN";
842 }
843 }
844
845 static const char *DestinationToString(USHORT usDestination)
846 {
847 switch (usDestination) {
848 case CONN_DST_NONE:
849 return "NONE";
850 case CONN_DST_ATTENUATION:
851 return "ATTENUATION";
852 case CONN_DST_PITCH:
853 return "PITCH";
854 case CONN_DST_PAN:
855 return "PAN";
856 case CONN_DST_LFO_FREQUENCY:
857 return "LFO_FREQUENCY";
858 case CONN_DST_LFO_STARTDELAY:
859 return "LFO_STARTDELAY";
860 case CONN_DST_EG1_ATTACKTIME:
861 return "EG1_ATTACKTIME";
862 case CONN_DST_EG1_DECAYTIME:
863 return "EG1_DECAYTIME";
864 case CONN_DST_EG1_RELEASETIME:
865 return "EG1_RELEASETIME";
866 case CONN_DST_EG1_SUSTAINLEVEL:
867 return "EG1_SUSTAINLEVEL";
868 case CONN_DST_EG2_ATTACKTIME:
869 return "EG2_ATTACKTIME";
870 case CONN_DST_EG2_DECAYTIME:
871 return "EG2_DECAYTIME";
872 case CONN_DST_EG2_RELEASETIME:
873 return "EG2_RELEASETIME";
874 case CONN_DST_EG2_SUSTAINLEVEL:
875 return "EG2_SUSTAINLEVEL";
876 case CONN_DST_KEYNUMBER:
877 return "KEYNUMBER";
878 case CONN_DST_LEFT:
879 return "LEFT";
880 case CONN_DST_RIGHT:
881 return "RIGHT";
882 case CONN_DST_CENTER:
883 return "CENTER";
884 case CONN_DST_LEFTREAR:
885 return "LEFTREAR";
886 case CONN_DST_RIGHTREAR:
887 return "RIGHTREAR";
888 case CONN_DST_LFE_CHANNEL:
889 return "LFE_CHANNEL";
890 case CONN_DST_CHORUS:
891 return "CHORUS";
892 case CONN_DST_REVERB:
893 return "REVERB";
894 case CONN_DST_VIB_FREQUENCY:
895 return "VIB_FREQUENCY";
896 case CONN_DST_VIB_STARTDELAY:
897 return "VIB_STARTDELAY";
898 case CONN_DST_EG1_DELAYTIME:
899 return "EG1_DELAYTIME";
900 case CONN_DST_EG1_HOLDTIME:
901 return "EG1_HOLDTIME";
902 case CONN_DST_EG1_SHUTDOWNTIME:
903 return "EG1_SHUTDOWNTIME";
904 case CONN_DST_EG2_DELAYTIME:
905 return "EG2_DELAYTIME";
906 case CONN_DST_EG2_HOLDTIME:
907 return "EG2_HOLDTIME";
908 case CONN_DST_FILTER_CUTOFF:
909 return "FILTER_CUTOFF";
910 case CONN_DST_FILTER_Q:
911 return "FILTER_Q";
912 default:
913 return "UNKOWN";
914 }
915 }
916
917 static void PrintArt(const char *type, CONNECTIONLIST *art, CONNECTION *artList)
918 {
919 Uint32 i;
920 printf("%s Connections:\n", type);
921 for ( i = 0; i < art->cConnections; ++i ) {
922 printf(" Source: %s, Control: %s, Destination: %s, Transform: %s, Scale: %d\n",
923 SourceToString(artList[i].usSource),
924 SourceToString(artList[i].usControl),
925 DestinationToString(artList[i].usDestination),
926 TransformToString(artList[i].usTransform),
927 artList[i].lScale);
928 }
929 }
930
931 static void PrintWave(DLS_Wave *wave, Uint32 index)
932 {
933 WaveFMT *format = wave->format;
934 if ( format ) {
935 printf(" Wave %u: Format: %hu, %hu channels, %u Hz, %hu bits (length = %u)\n", index, format->wFormatTag, format->wChannels, format->dwSamplesPerSec, format->wBitsPerSample, wave->length);
936 }
937 if ( wave->wsmp ) {
938 Uint32 i;
939 printf(" wsmp->usUnityNote = %hu\n", wave->wsmp->usUnityNote);
940 printf(" wsmp->sFineTune = %hd\n", wave->wsmp->sFineTune);
941 printf(" wsmp->lAttenuation = %d\n", wave->wsmp->lAttenuation);
942 printf(" wsmp->fulOptions = 0x%8.8x\n", wave->wsmp->fulOptions);
943 printf(" wsmp->cSampleLoops = %u\n", wave->wsmp->cSampleLoops);
944 for ( i = 0; i < wave->wsmp->cSampleLoops; ++i ) {
945 WLOOP *loop = &wave->wsmp_loop[i];
946 printf(" Loop %u:\n", i);
947 printf(" ulStart = %u\n", loop->ulStart);
948 printf(" ulLength = %u\n", loop->ulLength);
949 }
950 }
951 }
952
953 static void PrintRegion(DLS_Region *region, Uint32 index)
954 {
955 printf(" Region %u:\n", index);
956 if ( region->header ) {
957 printf(" RangeKey = { %hu - %hu }\n", region->header->RangeKey.usLow, region->header->RangeKey.usHigh);
958 printf(" RangeVelocity = { %hu - %hu }\n", region->header->RangeVelocity.usLow, region->header->RangeVelocity.usHigh);
959 printf(" fusOptions = 0x%4.4hx\n", region->header->fusOptions);
960 printf(" usKeyGroup = %hu\n", region->header->usKeyGroup);
961 }
962 if ( region->wlnk ) {
963 printf(" wlnk->fusOptions = 0x%4.4hx\n", region->wlnk->fusOptions);
964 printf(" wlnk->usPhaseGroup = %hu\n", region->wlnk->usPhaseGroup);
965 printf(" wlnk->ulChannel = %u\n", region->wlnk->ulChannel);
966 printf(" wlnk->ulTableIndex = %u\n", region->wlnk->ulTableIndex);
967 }
968 if ( region->wsmp ) {
969 Uint32 i;
970 printf(" wsmp->usUnityNote = %hu\n", region->wsmp->usUnityNote);
971 printf(" wsmp->sFineTune = %hd\n", region->wsmp->sFineTune);
972 printf(" wsmp->lAttenuation = %d\n", region->wsmp->lAttenuation);
973 printf(" wsmp->fulOptions = 0x%8.8x\n", region->wsmp->fulOptions);
974 printf(" wsmp->cSampleLoops = %u\n", region->wsmp->cSampleLoops);
975 for ( i = 0; i < region->wsmp->cSampleLoops; ++i ) {
976 WLOOP *loop = &region->wsmp_loop[i];
977 printf(" Loop %u:\n", i);
978 printf(" ulStart = %u\n", loop->ulStart);
979 printf(" ulLength = %u\n", loop->ulLength);
980 }
981 }
982 if ( region->art && region->art->cConnections > 0 ) {
983 PrintArt("Region", region->art, region->artList);
984 }
985 }
986
987 static void PrintInstrument(DLS_Instrument *instrument, Uint32 index)
988 {
989 printf("Instrument %u:\n", index);
990 if ( instrument->name ) {
991 printf(" Name: %s\n", instrument->name);
992 }
993 if ( instrument->header ) {
994 Uint32 i;
995 printf(" ulBank = 0x%8.8x\n", instrument->header->Locale.ulBank);
996 printf(" ulInstrument = %u\n", instrument->header->Locale.ulInstrument);
997 printf(" Regions: %u\n", instrument->header->cRegions);
998 for ( i = 0; i < instrument->header->cRegions; ++i ) {
999 PrintRegion(&instrument->regions[i], i);
1000 }
1001 }
1002 if ( instrument->art && instrument->art->cConnections > 0 ) {
1003 PrintArt("Instrument", instrument->art, instrument->artList);
1004 }
1005 };
1006
1007 void PrintDLS(DLS_Data *data)
1008 {
1009 printf("DLS Data:\n");
1010 printf("cInstruments = %u\n", data->cInstruments);
1011 if ( data->instruments ) {
1012 Uint32 i;
1013 for ( i = 0; i < data->cInstruments; ++i ) {
1014 PrintInstrument(&data->instruments[i], i);
1015 }
1016 }
1017 if ( data->ptbl && data->ptbl->cCues > 0 ) {
1018 Uint32 i;
1019 printf("Cues: ");
1020 for ( i = 0; i < data->ptbl->cCues; ++i ) {
1021 if ( i > 0 ) {
1022 printf(", ");
1023 }
1024 printf("%u", data->ptblList[i].ulOffset);
1025 }
1026 printf("\n");
1027 }
1028 if ( data->waveList ) {
1029 Uint32 i;
1030 printf("Waves:\n");
1031 for ( i = 0; i < data->ptbl->cCues; ++i ) {
1032 PrintWave(&data->waveList[i], i);
1033 }
1034 }
1035 if ( data->name ) {
1036 printf("Name: %s\n", data->name);
1037 }
1038 if ( data->artist ) {
1039 printf("Artist: %s\n", data->artist);
1040 }
1041 if ( data->copyright ) {
1042 printf("Copyright: %s\n", data->copyright);
1043 }
1044 if ( data->comments ) {
1045 printf("Comments: %s\n", data->comments);
1046 }
1047 }
1048
1049 #ifdef TEST_MAIN_DLS
1050
1051 main(int argc, char *argv[])
1052 {
1053 int i;
1054 for ( i = 1; i < argc; ++i ) {
1055 DLS_Data *data;
1056 SDL_RWops *src = SDL_RWFromFile(argv[i], "rb");
1057 if ( !src ) {
1058 fprintf(stderr, "Couldn't open %s: %s", argv[i], SDL_GetError());
1059 continue;
1060 }
1061 data = LoadDLS(src);
1062 if ( data ) {
1063 PrintRIFF(data->chunk, 0);
1064 PrintDLS(data);
1065 FreeDLS(data);
1066 } else {
1067 fprintf(stderr, "Couldn't load %s: %s\n", argv[i], SDL_GetError());
1068 }
1069 SDL_RWclose(src);
1070 }
1071 }
1072
1073 #endif // TEST_MAIN
1074 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1075
1076 /*-------------------------------------------------------------------------*/
1077 /* * * * * * * * * * * * * * * * * instrum_dls.c * * * * * * * * * * * * * */
1078 /*-------------------------------------------------------------------------*/
1079
1080 DLS_Data *Timidity_LoadDLS(SDL_RWops *src)
1081 {
1082 DLS_Data *patches = LoadDLS(src);
1083 if (!patches) {
1084 SNDDBG(("%s", SDL_GetError()));
1085 }
1086 return patches;
1087 }
1088
1089 void Timidity_FreeDLS(DLS_Data *patches)
1090 {
1091 FreeDLS(patches);
1092 }
1093
1094 /* convert timecents to sec */
1095 static double to_msec(int timecent)
1096 {
1097 if (timecent == 0x80000000 || timecent == 0)
1098 return 0.0;
1099 return 1000.0 * pow(2.0, (double)(timecent / 65536) / 1200.0);
1100 }
1101
1102 /* convert decipercent to {0..1} */
1103 static double to_normalized_percent(int decipercent)
1104 {
1105 return ((double)(decipercent / 65536)) / 1000.0;
1106 }
1107
1108 /* convert from 8bit value to fractional offset (15.15) */
1109 static Sint32 to_offset(int offset)
1110 {
1111 return (Sint32)offset << (7+15);
1112 }
1113
1114 /* calculate ramp rate in fractional unit;
1115 * diff = 8bit, time = msec
1116 */
1117 static Sint32 calc_rate(MidiSong *song, int diff, int sample_rate, double msec)
1118 {
1119 double rate;
1120
1121 if(msec < 6)
1122 msec = 6;
1123 if(diff == 0)
1124 diff = 255;
1125 diff <<= (7+15);
1126 rate = ((double)diff / song->rate) * song->control_ratio * 1000.0 / msec;
1127 return (Sint32)rate;
1128 }
1129
1130 static int load_connection(ULONG cConnections, CONNECTION *artList, USHORT destination)
1131 {
1132 ULONG i;
1133 int value = 0;
1134 for (i = 0; i < cConnections; ++i) {
1135 CONNECTION *conn = &artList[i];
1136 if(conn->usDestination == destination) {
1137 // The formula for the destination is:
1138 // usDestination = usDestination + usTransform(usSource * (usControl * lScale))
1139 // Since we are only handling source/control of NONE and identity
1140 // transform, this simplifies to: usDestination = usDestination + lScale
1141 if (conn->usSource == CONN_SRC_NONE &&
1142 conn->usControl == CONN_SRC_NONE &&
1143 conn->usTransform == CONN_TRN_NONE)
1144 value += conn->lScale;
1145 }
1146 }
1147 return value;
1148 }
1149
1150 static void load_region_dls(MidiSong *song, Sample *sample, DLS_Instrument *ins, Uint32 index)
1151 {
1152 DLS_Region *rgn = &ins->regions[index];
1153 DLS_Wave *wave = &song->patches->waveList[rgn->wlnk->ulTableIndex];
1154
1155 sample->low_freq = freq_table[rgn->header->RangeKey.usLow];
1156 sample->high_freq = freq_table[rgn->header->RangeKey.usHigh];
1157 sample->root_freq = freq_table[rgn->wsmp->usUnityNote];
1158 sample->low_vel = rgn->header->RangeVelocity.usLow;
1159 sample->high_vel = rgn->header->RangeVelocity.usHigh;
1160
1161 sample->modes = MODES_16BIT;
1162 sample->sample_rate = wave->format->dwSamplesPerSec;
1163 sample->data_length = wave->length / 2;
1164 sample->data = (sample_t *)safe_malloc(wave->length);
1165 memcpy(sample->data, wave->data, wave->length);
1166 if (rgn->wsmp->cSampleLoops) {
1167 sample->modes |= (MODES_LOOPING|MODES_SUSTAIN);
1168 sample->loop_start = rgn->wsmp_loop->ulStart / 2;
1169 sample->loop_end = sample->loop_start + (rgn->wsmp_loop->ulLength / 2);
1170 }
1171 sample->volume = 1.0f;
1172
1173 if (sample->modes & MODES_SUSTAIN) {
1174 int value;
1175 double attack, hold, decay, release; int sustain;
1176 CONNECTIONLIST *art = NULL;
1177 CONNECTION *artList = NULL;
1178
1179 if (ins->art && ins->art->cConnections > 0 && ins->artList) {
1180 art = ins->art;
1181 artList = ins->artList;
1182 } else {
1183 art = rgn->art;
1184 artList = rgn->artList;
1185 }
1186
1187 value = load_connection(art->cConnections, artList, CONN_DST_EG1_ATTACKTIME);
1188 attack = to_msec(value);
1189 value = load_connection(art->cConnections, artList, CONN_DST_EG1_HOLDTIME);
1190 hold = to_msec(value);
1191 value = load_connection(art->cConnections, artList, CONN_DST_EG1_DECAYTIME);
1192 decay = to_msec(value);
1193 value = load_connection(art->cConnections, artList, CONN_DST_EG1_RELEASETIME);
1194 release = to_msec(value);
1195 value = load_connection(art->cConnections, artList, CONN_DST_EG1_SUSTAINLEVEL);
1196 sustain = (int)((1.0 - to_normalized_percent(value)) * 250.0);
1197 value = load_connection(art->cConnections, artList, CONN_DST_PAN);
1198 sample->panning = (int)((0.5 + to_normalized_percent(value)) * 127.0);
1199
1200 /*
1201 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);
1202 */
1203
1204 sample->envelope_offset[0] = to_offset(255);
1205 sample->envelope_rate[0] = calc_rate(song, 255, sample->sample_rate, attack);
1206
1207 sample->envelope_offset[1] = to_offset(250);
1208 sample->envelope_rate[1] = calc_rate(song, 5, sample->sample_rate, hold);
1209
1210 sample->envelope_offset[2] = to_offset(sustain);
1211 sample->envelope_rate[2] = calc_rate(song, 255 - sustain, sample->sample_rate, decay);
1212
1213 sample->envelope_offset[3] = to_offset(0);
1214 sample->envelope_rate[3] = calc_rate(song, 5 + sustain, sample->sample_rate, release);
1215
1216 sample->envelope_offset[4] = to_offset(0);
1217 sample->envelope_rate[4] = to_offset(1);
1218
1219 sample->envelope_offset[5] = to_offset(0);
1220 sample->envelope_rate[5] = to_offset(1);
1221
1222 sample->modes |= MODES_ENVELOPE;
1223 }
1224
1225 sample->data_length <<= FRACTION_BITS;
1226 sample->loop_start <<= FRACTION_BITS;
1227 sample->loop_end <<= FRACTION_BITS;
1228 }
1229
1230 Instrument *load_instrument_dls(MidiSong *song, int drum, int bank, int instrument)
1231 {
1232 Instrument *inst;
1233 Uint32 i;
1234 DLS_Instrument *dls_ins;
1235
1236 if (!song->patches)
1237 return(NULL);
1238
1239 drum = drum ? 0x80000000 : 0;
1240 for (i = 0; i < song->patches->cInstruments; ++i) {
1241 dls_ins = &song->patches->instruments[i];
1242 if ((dls_ins->header->Locale.ulBank & 0x80000000) == drum &&
1243 ((dls_ins->header->Locale.ulBank >> 8) & 0xFF) == bank &&
1244 dls_ins->header->Locale.ulInstrument == instrument)
1245 break;
1246 }
1247 if (i == song->patches->cInstruments && !bank) {
1248 for (i = 0; i < song->patches->cInstruments; ++i) {
1249 dls_ins = &song->patches->instruments[i];
1250 if ((dls_ins->header->Locale.ulBank & 0x80000000) == drum &&
1251 dls_ins->header->Locale.ulInstrument == instrument)
1252 break;
1253 }
1254 }
1255 if (i == song->patches->cInstruments) {
1256 SNDDBG(("Couldn't find %s instrument %d in bank %d\n", drum ? "drum" : "melodic", instrument, bank));
1257 return(NULL);
1258 }
1259
1260 inst = (Instrument *)safe_malloc(sizeof(*inst));
1261 inst->samples = dls_ins->header->cRegions;
1262 inst->sample = (Sample *)safe_malloc(inst->samples * sizeof(*inst->sample));
1263 memset(inst->sample, 0, inst->samples * sizeof(*inst->sample));
1264 /*
1265 printf("Found %s instrument %d in bank %d named %s with %d regions\n", drum ? "drum" : "melodic", instrument, bank, dls_ins->name, inst->samples);
1266 */
1267 for (i = 0; i < dls_ins->header->cRegions; ++i) {
1268 load_region_dls(song, &inst->sample[i], dls_ins, i);
1269 }
1270 return(inst);
1271 }