fixed ticket [f9c074e766ade1bd] (pickups should not be infinitely tall) (i hope ;-)
[k8vavoom.git] / libs / timidity / instrum_dls.cpp
blobfe3a2d2e39ddf0c9de3308f155d82fd920c1ef42
1 /*
3 TiMidity -- Experimental MIDI to WAVE converter
4 Copyright (C) 1995 Tuukka Toivonen <toivonen@clinet.fi>
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.
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.
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.
20 instrum.h
24 #include <stdlib.h>
25 #include <string.h>
27 #include "timidity.h"
29 #define __Sound_SetError(x)
31 namespace LibTimidity
34 /*-------------------------------------------------------------------------*/
35 /* * * * * * * * * * * * * * * * * load_riff.h * * * * * * * * * * * * * * */
36 /*-------------------------------------------------------------------------*/
37 struct RIFF_Chunk
39 uint32 magic;
40 uint32 length;
41 uint32 subtype;
42 uint8 *data;
43 RIFF_Chunk *child;
44 RIFF_Chunk *next;
47 extern RIFF_Chunk* LoadRIFF(FILE *src);
48 extern void FreeRIFF(RIFF_Chunk *chunk);
49 extern void PrintRIFF(RIFF_Chunk *chunk, int level);
50 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
52 /*-------------------------------------------------------------------------*/
53 /* * * * * * * * * * * * * * * * * load_riff.c * * * * * * * * * * * * * * */
54 /*-------------------------------------------------------------------------*/
55 #define RIFF 0x46464952 /* "RIFF" */
56 #define LIST 0x5453494c /* "LIST" */
58 static RIFF_Chunk *AllocRIFFChunk()
60 RIFF_Chunk *chunk = (RIFF_Chunk *)safe_malloc(sizeof(*chunk));
62 if (!chunk)
64 __Sound_SetError(ERR_OUT_OF_MEMORY);
65 return NULL;
67 memset(chunk, 0, sizeof(*chunk));
69 return chunk;
72 static void FreeRIFFChunk(RIFF_Chunk *chunk)
74 if (chunk->child)
76 FreeRIFFChunk(chunk->child);
79 if (chunk->next)
81 FreeRIFFChunk(chunk->next);
83 free(chunk);
84 chunk = NULL;
87 static int ChunkHasSubType(uint32 magic)
89 static uint32 chunk_list[] =
91 RIFF, LIST
93 int i;
95 for (i = 0; i < sizeof(chunk_list) / sizeof(chunk_list[0]); ++i)
97 if (magic == chunk_list[i])
99 return 1;
103 return 0;
106 static int ChunkHasSubChunks(uint32 magic)
108 static uint32 chunk_list[] =
110 RIFF, LIST
112 int i;
114 for (i = 0; i < sizeof(chunk_list) / sizeof(chunk_list[0]); ++i)
116 if (magic == chunk_list[i])
118 return 1;
122 return 0;
125 static void LoadSubChunks(RIFF_Chunk *chunk, uint8 *data, uint32 left)
127 uint8 *subchunkData;
128 uint32 subchunkDataLen;
130 while (left > 8)
132 RIFF_Chunk *child = AllocRIFFChunk();
133 RIFF_Chunk *next, *prev = NULL;
135 for (next = chunk->child; next; next = next->next)
137 prev = next;
140 if (prev)
142 prev->next = child;
144 else
146 chunk->child = child;
148 child->magic = (data[0] << 0) | (data[1] << 8) |
149 (data[2] << 16) | (data[3] << 24);
150 data += 4;
151 left -= 4;
152 child->length = (data[0] << 0) | (data[1] << 8) |
153 (data[2] << 16) | (data[3] << 24);
154 data += 4;
155 left -= 4;
156 child->data = data;
158 if (child->length > left)
160 child->length = left;
162 subchunkData = child->data;
163 subchunkDataLen = child->length;
165 if (ChunkHasSubType(child->magic) && subchunkDataLen >= 4)
167 child->subtype = (subchunkData[0] << 0) | (subchunkData[1] << 8) |
168 (subchunkData[2] << 16) | (subchunkData[3] << 24);
169 subchunkData += 4;
170 subchunkDataLen -= 4;
173 if (ChunkHasSubChunks(child->magic))
175 LoadSubChunks(child, subchunkData, subchunkDataLen);
177 data += (child->length + 1) & ~1;
178 left -= (child->length + 1) & ~1;
182 RIFF_Chunk *LoadRIFF(FILE* src)
184 RIFF_Chunk *chunk;
185 uint8 *subchunkData;
186 uint32 subchunkDataLen;
188 /* Allocate the chunk structure */
189 chunk = AllocRIFFChunk();
191 /* Make sure the file is in RIFF format */
192 fread(&chunk->magic, 4, 1, src);
193 fread(&chunk->length, 4, 1, src);
194 chunk->magic = LE_LONG(chunk->magic);
195 chunk->length = LE_LONG(chunk->length);
197 if (chunk->magic != RIFF)
199 __Sound_SetError("Not a RIFF file");
200 FreeRIFFChunk(chunk);
202 return NULL;
204 chunk->data = (uint8 *)safe_malloc(chunk->length);
206 if (chunk->data == NULL)
208 __Sound_SetError(ERR_OUT_OF_MEMORY);
209 FreeRIFFChunk(chunk);
211 return NULL;
214 if (fread(chunk->data, chunk->length, 1, src) != 1)
216 __Sound_SetError(ERR_IO_ERROR);
217 FreeRIFF(chunk);
219 return NULL;
221 subchunkData = chunk->data;
222 subchunkDataLen = chunk->length;
224 if (ChunkHasSubType(chunk->magic) && subchunkDataLen >= 4)
226 chunk->subtype = (subchunkData[0] << 0) | (subchunkData[1] << 8) |
227 (subchunkData[2] << 16) | (subchunkData[3] << 24);
228 subchunkData += 4;
229 subchunkDataLen -= 4;
232 if (ChunkHasSubChunks(chunk->magic))
234 LoadSubChunks(chunk, subchunkData, subchunkDataLen);
237 return chunk;
240 void FreeRIFF(RIFF_Chunk *chunk)
242 free(chunk->data);
243 chunk->data = NULL;
244 FreeRIFFChunk(chunk);
247 /*-------------------------------------------------------------------------*/
248 /* * * * * * * * * * * * * * * * * load_dls.h * * * * * * * * * * * * * * */
249 /*-------------------------------------------------------------------------*/
250 /* This code is based on the DLS spec version 1.1, available at:
251 http://www.midi.org/about-midi/dls/dlsspec.shtml
254 /* Some typedefs so the public dls headers don't need to be modified */
255 #define FAR
256 typedef uint8 BYTE;
257 typedef int16 SHORT;
258 typedef uint16 USHORT;
259 typedef uint16 WORD;
260 typedef int32 LONG;
261 typedef uint32 ULONG;
262 typedef uint32 DWORD;
263 #define mmioFOURCC(A, B, C, D) \
264 (((A) << 0) | ((B) << 8) | ((C) << 16) | ((D) << 24))
265 #define DEFINE_GUID(A, B, C, E, F, G, H, I, J, K, L, M)
267 #include "dls1.h"
268 #include "dls2.h"
270 struct WaveFMT
272 WORD wFormatTag;
273 WORD wChannels;
274 DWORD dwSamplesPerSec;
275 DWORD dwAvgBytesPerSec;
276 WORD wBlockAlign;
277 WORD wBitsPerSample;
280 struct DLS_Wave
282 WaveFMT *format;
283 uint8 *data;
284 uint32 length;
285 WSMPL *wsmp;
286 WLOOP *wsmp_loop;
289 struct DLS_Region
291 RGNHEADER *header;
292 WAVELINK *wlnk;
293 WSMPL *wsmp;
294 WLOOP *wsmp_loop;
295 CONNECTIONLIST *art;
296 CONNECTION *artList;
299 struct DLS_Instrument
301 const char *name;
302 INSTHEADER *header;
303 DLS_Region *regions;
304 CONNECTIONLIST *art;
305 CONNECTION *artList;
308 struct DLS_Data
310 RIFF_Chunk *chunk;
312 uint32 cInstruments;
313 DLS_Instrument *instruments;
315 POOLTABLE *ptbl;
316 POOLCUE *ptblList;
317 DLS_Wave *waveList;
319 const char *name;
320 const char *artist;
321 const char *copyright;
322 const char *comments;
325 extern DLS_Data* LoadDLS(FILE *src);
326 extern void FreeDLS(DLS_Data *chunk);
327 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
329 /*-------------------------------------------------------------------------*/
330 /* * * * * * * * * * * * * * * * * load_dls.c * * * * * * * * * * * * * * */
331 /*-------------------------------------------------------------------------*/
333 #define FOURCC_LIST 0x5453494c /* "LIST" */
334 #define FOURCC_FMT 0x20746D66 /* "fmt " */
335 #define FOURCC_DATA 0x61746164 /* "data" */
336 #define FOURCC_INFO mmioFOURCC('I','N','F','O')
337 #define FOURCC_IARL mmioFOURCC('I','A','R','L')
338 #define FOURCC_IART mmioFOURCC('I','A','R','T')
339 #define FOURCC_ICMS mmioFOURCC('I','C','M','S')
340 #define FOURCC_ICMT mmioFOURCC('I','C','M','T')
341 #define FOURCC_ICOP mmioFOURCC('I','C','O','P')
342 #define FOURCC_ICRD mmioFOURCC('I','C','R','D')
343 #define FOURCC_IENG mmioFOURCC('I','E','N','G')
344 #define FOURCC_IGNR mmioFOURCC('I','G','N','R')
345 #define FOURCC_IKEY mmioFOURCC('I','K','E','Y')
346 #define FOURCC_IMED mmioFOURCC('I','M','E','D')
347 #define FOURCC_INAM mmioFOURCC('I','N','A','M')
348 #define FOURCC_IPRD mmioFOURCC('I','P','R','D')
349 #define FOURCC_ISBJ mmioFOURCC('I','S','B','J')
350 #define FOURCC_ISFT mmioFOURCC('I','S','F','T')
351 #define FOURCC_ISRC mmioFOURCC('I','S','R','C')
352 #define FOURCC_ISRF mmioFOURCC('I','S','R','F')
353 #define FOURCC_ITCH mmioFOURCC('I','T','C','H')
356 static void FreeRegions(DLS_Instrument *instrument)
358 if (instrument->regions)
360 free(instrument->regions);
361 instrument->regions = NULL;
365 static void AllocRegions(DLS_Instrument *instrument)
367 int datalen = (instrument->header->cRegions * sizeof(DLS_Region));
369 FreeRegions(instrument);
370 instrument->regions = (DLS_Region *)safe_malloc(datalen);
372 if (instrument->regions)
374 memset(instrument->regions, 0, datalen);
378 static void FreeInstruments(DLS_Data *data)
380 if (data->instruments)
382 uint32 i;
384 for (i = 0; i < data->cInstruments; ++i)
386 FreeRegions(&data->instruments[i]);
388 free(data->instruments);
389 data->instruments = NULL;
393 static void AllocInstruments(DLS_Data *data)
395 int datalen = (data->cInstruments * sizeof(DLS_Instrument));
397 FreeInstruments(data);
398 data->instruments = (DLS_Instrument *)safe_malloc(datalen);
399 if (data->instruments)
401 memset(data->instruments, 0, datalen);
405 static void FreeWaveList(DLS_Data *data)
407 if (data->waveList)
409 free(data->waveList);
410 data->waveList = NULL;
414 static void AllocWaveList(DLS_Data *data)
416 int datalen = (data->ptbl->cCues * sizeof(DLS_Wave));
418 FreeWaveList(data);
419 data->waveList = (DLS_Wave *)safe_malloc(datalen);
420 if (data->waveList)
422 memset(data->waveList, 0, datalen);
426 static void Parse_colh(DLS_Data *data, RIFF_Chunk *chunk)
428 data->cInstruments = LE_LONG(*(uint32 *)chunk->data);
429 AllocInstruments(data);
432 static void Parse_insh(DLS_Data * /*data*/, RIFF_Chunk *chunk, DLS_Instrument *instrument)
434 INSTHEADER *header = (INSTHEADER *)chunk->data;
435 header->cRegions = LE_LONG(header->cRegions);
436 header->Locale.ulBank = LE_LONG(header->Locale.ulBank);
437 header->Locale.ulInstrument = LE_LONG(header->Locale.ulInstrument);
438 instrument->header = header;
439 AllocRegions(instrument);
442 static void Parse_rgnh(DLS_Data * /*data*/, RIFF_Chunk *chunk, DLS_Region *region)
444 RGNHEADER *header = (RGNHEADER *)chunk->data;
445 header->RangeKey.usLow = LE_SHORT(header->RangeKey.usLow);
446 header->RangeKey.usHigh = LE_SHORT(header->RangeKey.usHigh);
447 header->RangeVelocity.usLow = LE_SHORT(header->RangeVelocity.usLow);
448 header->RangeVelocity.usHigh = LE_SHORT(header->RangeVelocity.usHigh);
449 header->fusOptions = LE_SHORT(header->fusOptions);
450 header->usKeyGroup = LE_SHORT(header->usKeyGroup);
451 region->header = header;
454 static void Parse_wlnk(DLS_Data * /*data*/, RIFF_Chunk *chunk, DLS_Region *region)
456 WAVELINK *wlnk = (WAVELINK *)chunk->data;
457 wlnk->fusOptions = LE_SHORT(wlnk->fusOptions);
458 wlnk->usPhaseGroup = LE_SHORT(wlnk->usPhaseGroup);
459 wlnk->ulChannel = LE_LONG(wlnk->ulChannel);
460 wlnk->ulTableIndex = LE_LONG(wlnk->ulTableIndex);
461 region->wlnk = wlnk;
464 static void Parse_wsmp(DLS_Data * /*data*/, RIFF_Chunk *chunk, WSMPL **wsmp_ptr, WLOOP **wsmp_loop_ptr)
466 uint32 i;
467 WSMPL *wsmp = (WSMPL *)chunk->data;
468 WLOOP *loop;
469 wsmp->cbSize = LE_LONG(wsmp->cbSize);
470 wsmp->usUnityNote = LE_SHORT(wsmp->usUnityNote);
471 wsmp->sFineTune = LE_SHORT(wsmp->sFineTune);
472 wsmp->lAttenuation = LE_LONG(wsmp->lAttenuation);
473 wsmp->fulOptions = LE_LONG(wsmp->fulOptions);
474 wsmp->cSampleLoops = LE_LONG(wsmp->cSampleLoops);
475 loop = (WLOOP *)((uint8 *)chunk->data + wsmp->cbSize);
476 *wsmp_ptr = wsmp;
477 *wsmp_loop_ptr = loop;
479 for (i = 0; i < wsmp->cSampleLoops; ++i)
481 loop->cbSize = LE_LONG(loop->cbSize);
482 loop->ulType = LE_LONG(loop->ulType);
483 loop->ulStart = LE_LONG(loop->ulStart);
484 loop->ulLength = LE_LONG(loop->ulLength);
485 ++loop;
489 static void Parse_art(DLS_Data * /*data*/, RIFF_Chunk *chunk, CONNECTIONLIST **art_ptr, CONNECTION **artList_ptr)
491 uint32 i;
492 CONNECTIONLIST *art = (CONNECTIONLIST *)chunk->data;
493 CONNECTION *artList;
494 art->cbSize = LE_LONG(art->cbSize);
495 art->cConnections = LE_LONG(art->cConnections);
496 artList = (CONNECTION *)((uint8 *)chunk->data + art->cbSize);
497 *art_ptr = art;
498 *artList_ptr = artList;
500 for (i = 0; i < art->cConnections; ++i)
502 artList->usSource = LE_SHORT(artList->usSource);
503 artList->usControl = LE_SHORT(artList->usControl);
504 artList->usDestination = LE_SHORT(artList->usDestination);
505 artList->usTransform = LE_SHORT(artList->usTransform);
506 artList->lScale = LE_LONG(artList->lScale);
507 ++artList;
511 static void Parse_lart(DLS_Data *data, RIFF_Chunk *chunk, CONNECTIONLIST **conn_ptr, CONNECTION **connList_ptr)
513 /* FIXME: This only supports one set of connections */
514 for (chunk = chunk->child; chunk; chunk = chunk->next)
516 uint32 magic = (chunk->magic == FOURCC_LIST) ? chunk->subtype : chunk->magic;
518 switch(magic)
520 case FOURCC_ART1:
521 case FOURCC_ART2:
523 Parse_art(data, chunk, conn_ptr, connList_ptr);
524 return;
530 static void Parse_rgn(DLS_Data *data, RIFF_Chunk *chunk, DLS_Region *region)
532 for (chunk = chunk->child; chunk; chunk = chunk->next)
534 uint32 magic = (chunk->magic == FOURCC_LIST) ? chunk->subtype : chunk->magic;
536 switch(magic)
538 case FOURCC_RGNH:
539 Parse_rgnh(data, chunk, region);
540 break;
541 case FOURCC_WLNK:
542 Parse_wlnk(data, chunk, region);
543 break;
544 case FOURCC_WSMP:
545 Parse_wsmp(data, chunk, &region->wsmp, &region->wsmp_loop);
546 break;
547 case FOURCC_LART:
548 case FOURCC_LAR2:
549 Parse_lart(data, chunk, &region->art, &region->artList);
550 break;
555 static void Parse_lrgn(DLS_Data *data, RIFF_Chunk *chunk, DLS_Instrument *instrument)
557 uint32 region = 0;
559 for (chunk = chunk->child; chunk; chunk = chunk->next)
561 uint32 magic = (chunk->magic == FOURCC_LIST) ? chunk->subtype : chunk->magic;
563 switch(magic)
565 case FOURCC_RGN:
566 case FOURCC_RGN2:
567 if (region < instrument->header->cRegions)
569 Parse_rgn(data, chunk, &instrument->regions[region++]);
571 break;
576 static void Parse_INFO_INS(DLS_Data * /*data*/, RIFF_Chunk *chunk, DLS_Instrument *instrument)
578 for (chunk = chunk->child; chunk; chunk = chunk->next)
580 uint32 magic = (chunk->magic == FOURCC_LIST) ? chunk->subtype : chunk->magic;
582 switch(magic)
584 case FOURCC_INAM: /* Name */
585 instrument->name = (const char*)chunk->data;
586 break;
591 static void Parse_ins(DLS_Data *data, RIFF_Chunk *chunk, DLS_Instrument *instrument)
593 for (chunk = chunk->child; chunk; chunk = chunk->next)
595 uint32 magic = (chunk->magic == FOURCC_LIST) ? chunk->subtype : chunk->magic;
597 switch(magic)
599 case FOURCC_INSH:
600 Parse_insh(data, chunk, instrument);
601 break;
602 case FOURCC_LRGN:
603 Parse_lrgn(data, chunk, instrument);
604 break;
605 case FOURCC_LART:
606 case FOURCC_LAR2:
607 Parse_lart(data, chunk, &instrument->art, &instrument->artList);
608 break;
609 case FOURCC_INFO:
610 Parse_INFO_INS(data, chunk, instrument);
611 break;
616 static void Parse_lins(DLS_Data *data, RIFF_Chunk *chunk)
618 uint32 instrument = 0;
620 for (chunk = chunk->child; chunk; chunk = chunk->next)
622 uint32 magic = (chunk->magic == FOURCC_LIST) ? chunk->subtype : chunk->magic;
624 switch(magic)
626 case FOURCC_INS:
627 if (instrument < data->cInstruments)
629 Parse_ins(data, chunk, &data->instruments[instrument++]);
631 break;
636 static void Parse_ptbl(DLS_Data *data, RIFF_Chunk *chunk)
638 uint32 i;
639 POOLTABLE *ptbl = (POOLTABLE *)chunk->data;
640 ptbl->cbSize = LE_LONG(ptbl->cbSize);
641 ptbl->cCues = LE_LONG(ptbl->cCues);
642 data->ptbl = ptbl;
643 data->ptblList = (POOLCUE *)((uint8 *)chunk->data + ptbl->cbSize);
645 for (i = 0; i < ptbl->cCues; ++i)
647 data->ptblList[i].ulOffset = LE_LONG(data->ptblList[i].ulOffset);
649 AllocWaveList(data);
652 static void Parse_fmt(DLS_Data * /*data*/, RIFF_Chunk *chunk, DLS_Wave *wave)
654 WaveFMT *fmt = (WaveFMT *)chunk->data;
655 fmt->wFormatTag = LE_SHORT(fmt->wFormatTag);
656 fmt->wChannels = LE_SHORT(fmt->wChannels);
657 fmt->dwSamplesPerSec = LE_LONG(fmt->dwSamplesPerSec);
658 fmt->dwAvgBytesPerSec = LE_LONG(fmt->dwAvgBytesPerSec);
659 fmt->wBlockAlign = LE_SHORT(fmt->wBlockAlign);
660 fmt->wBitsPerSample = LE_SHORT(fmt->wBitsPerSample);
661 wave->format = fmt;
664 static void Parse_data(DLS_Data * /*data*/, RIFF_Chunk *chunk, DLS_Wave *wave)
666 wave->data = chunk->data;
667 wave->length = chunk->length;
670 static void Parse_wave(DLS_Data *data, RIFF_Chunk *chunk, DLS_Wave *wave)
672 for (chunk = chunk->child; chunk; chunk = chunk->next)
674 uint32 magic = (chunk->magic == FOURCC_LIST) ? chunk->subtype : chunk->magic;
676 switch(magic)
678 case FOURCC_FMT:
679 Parse_fmt(data, chunk, wave);
680 break;
681 case FOURCC_DATA:
682 Parse_data(data, chunk, wave);
683 break;
684 case FOURCC_WSMP:
685 Parse_wsmp(data, chunk, &wave->wsmp, &wave->wsmp_loop);
686 break;
691 static void Parse_wvpl(DLS_Data *data, RIFF_Chunk *chunk)
693 uint32 wave = 0;
695 for (chunk = chunk->child; chunk; chunk = chunk->next)
697 uint32 magic = (chunk->magic == FOURCC_LIST) ? chunk->subtype : chunk->magic;
699 switch(magic)
701 case FOURCC_wave:
702 if (wave < data->ptbl->cCues)
704 Parse_wave(data, chunk, &data->waveList[wave++]);
706 break;
711 static void Parse_INFO_DLS(DLS_Data *data, RIFF_Chunk *chunk)
713 for (chunk = chunk->child; chunk; chunk = chunk->next)
715 uint32 magic = (chunk->magic == FOURCC_LIST) ? chunk->subtype : chunk->magic;
717 switch(magic)
719 case FOURCC_IARL: /* Archival Location */
720 break;
721 case FOURCC_IART: /* Artist */
722 data->artist = (const char*)chunk->data;
723 break;
724 case FOURCC_ICMS: /* Commisioned */
725 break;
726 case FOURCC_ICMT: /* Comments */
727 data->comments = (const char*)chunk->data;
728 break;
729 case FOURCC_ICOP: /* Copyright */
730 data->copyright = (const char*)chunk->data;
731 break;
732 case FOURCC_ICRD: /* Creation Date */
733 break;
734 case FOURCC_IENG: /* Engineer */
735 break;
736 case FOURCC_IGNR: /* Genre */
737 break;
738 case FOURCC_IKEY: /* Keywords */
739 break;
740 case FOURCC_IMED: /* Medium */
741 break;
742 case FOURCC_INAM: /* Name */
743 data->name = (const char*)chunk->data;
744 break;
745 case FOURCC_IPRD: /* Product */
746 break;
747 case FOURCC_ISBJ: /* Subject */
748 break;
749 case FOURCC_ISFT: /* Software */
750 break;
751 case FOURCC_ISRC: /* Source */
752 break;
753 case FOURCC_ISRF: /* Source Form */
754 break;
755 case FOURCC_ITCH: /* Technician */
756 break;
761 DLS_Data *LoadDLS(FILE *src)
763 RIFF_Chunk *chunk;
764 DLS_Data *data = (DLS_Data *)safe_malloc(sizeof(*data));
766 if (!data)
768 __Sound_SetError(ERR_OUT_OF_MEMORY);
769 return NULL;
771 memset(data, 0, sizeof(*data));
772 data->chunk = LoadRIFF(src);
774 if (!data->chunk)
776 FreeDLS(data);
777 return NULL;
780 for (chunk = data->chunk->child; chunk; chunk = chunk->next)
782 uint32 magic = (chunk->magic == FOURCC_LIST) ? chunk->subtype : chunk->magic;
784 switch(magic)
786 case FOURCC_COLH:
787 Parse_colh(data, chunk);
788 break;
789 case FOURCC_LINS:
790 Parse_lins(data, chunk);
791 break;
792 case FOURCC_PTBL:
793 Parse_ptbl(data, chunk);
794 break;
795 case FOURCC_WVPL:
796 Parse_wvpl(data, chunk);
797 break;
798 case FOURCC_INFO:
799 Parse_INFO_DLS(data, chunk);
800 break;
804 return data;
807 void FreeDLS(DLS_Data *data)
809 if (data->chunk)
811 FreeRIFF(data->chunk);
813 FreeInstruments(data);
814 FreeWaveList(data);
815 free(data);
816 data = NULL;
819 /*-------------------------------------------------------------------------*/
820 /* * * * * * * * * * * * * * * * * instrum_dls.c * * * * * * * * * * * * * */
821 /*-------------------------------------------------------------------------*/
823 DLS_Data *Timidity_LoadDLS(FILE *src)
825 DLS_Data *patches = LoadDLS(src);
826 //if (!patches)
828 // SNDDBG(("%s", SDL_GetError()));
831 return patches;
834 void Timidity_FreeDLS(DLS_Data *patches)
836 FreeDLS(patches);
840 static double RelativeGainToLinear(int centibels)
842 // v = 10^(cb/(200*65536)) * V
843 return 100.0 * pow(10.0, (double)(centibels / 65536) / 200.0);
847 /* convert timecents to sec */
848 static double to_msec(int timecent)
850 if (timecent == 0x80000000)
852 return 0.0;
855 return 1000.0 * pow(2.0, (double)(timecent / 65536) / 1200.0);
858 /* convert decipercent to {0..1} */
859 static double to_normalized_percent(int decipercent)
861 return ((double)(decipercent / 65536)) / 1000.0;
864 /* convert from 8bit value to fractional offset (15.15) */
865 static int32 to_offset(int offset)
867 return (int32)offset << (7+15);
870 /* calculate ramp rate in fractional unit;
871 * diff = 8bit, time = msec
873 static int32 calc_rate(MidiSong* song, int diff, int /*sample_rate*/, double msec)
875 double rate;
877 if(msec < 6)
879 msec = 6;
882 if(diff == 0)
884 diff = 255;
886 diff <<= (7+15);
887 rate = ((double)diff / OUTPUT_RATE) * song->control_ratio * 1000.0 / msec;
889 return (int32)rate;
892 static int load_connection(ULONG cConnections, CONNECTION *artList, USHORT destination)
894 ULONG i;
895 int value = 0;
897 for (i = 0; i < cConnections; ++i)
899 CONNECTION *conn = &artList[i];
901 if(conn->usDestination == destination)
903 // The formula for the destination is:
904 // usDestination = usDestination + usTransform(usSource * (usControl * lScale))
905 // Since we are only handling source/control of NONE and identity
906 // transform, this simplifies to: usDestination = usDestination + lScale
907 if (conn->usSource == CONN_SRC_NONE &&
908 conn->usControl == CONN_SRC_NONE &&
909 conn->usTransform == CONN_TRN_NONE)
911 if (destination == CONN_DST_EG1_ATTACKTIME)
913 if (conn->lScale > 78743200)
915 conn->lScale -= 78743200; // maximum velocity
919 if (destination == CONN_DST_EG1_SUSTAINLEVEL)
921 conn->lScale /= (1000*512);
924 if (destination == CONN_DST_PAN)
926 conn->lScale /= (65536000/128);
928 value += conn->lScale;
933 return value;
936 static void load_region_dls(MidiSong* song, DLS_Data *patches, Sample *sample, DLS_Instrument *ins, uint32 index)
938 DLS_Region *rgn = &ins->regions[index];
939 DLS_Wave *wave = &patches->waveList[rgn->wlnk->ulTableIndex];
941 sample->low_freq = freq_table[rgn->header->RangeKey.usLow];
942 sample->high_freq = freq_table[rgn->header->RangeKey.usHigh];
943 sample->root_freq = freq_table[rgn->wsmp->usUnityNote];
944 sample->low_vel = rgn->header->RangeVelocity.usLow;
945 sample->high_vel = rgn->header->RangeVelocity.usHigh;
947 sample->modes = MODES_16BIT;
948 sample->sample_rate = wave->format->dwSamplesPerSec;
949 sample->data_length = wave->length / 2;
950 sample->data = (sample_t *)safe_malloc(wave->length);
951 memcpy(sample->data, wave->data, wave->length);
953 if (rgn->wsmp->cSampleLoops)
955 sample->modes |= (MODES_LOOPING|MODES_SUSTAIN);
956 sample->loop_start = rgn->wsmp_loop->ulStart / 2;
957 sample->loop_end = sample->loop_start + (rgn->wsmp_loop->ulLength / 2);
959 sample->volume = 1.0f;
961 if (sample->modes & MODES_SUSTAIN)
963 int value;
964 double attack, hold, decay, release;
965 int sustain;
966 CONNECTIONLIST *art = NULL;
967 CONNECTION *artList = NULL;
969 if (ins->art && ins->art->cConnections > 0 && ins->artList)
971 art = ins->art;
972 artList = ins->artList;
974 else
976 art = rgn->art;
977 artList = rgn->artList;
980 value = load_connection(art->cConnections, artList, CONN_DST_EG1_ATTACKTIME);
981 attack = to_msec(value);
982 if (attack < 0)
984 attack = 0;
986 if (attack >= 20)
988 attack = attack / 20;
991 value = load_connection(art->cConnections, artList, CONN_DST_EG1_HOLDTIME);
992 hold = to_msec(value);
993 if (hold >= 20)
995 hold = hold / 20;
998 value = load_connection(art->cConnections, artList, CONN_DST_EG1_DECAYTIME);
999 decay = to_msec(value);
1000 if (decay >= 20)
1002 decay = decay / 20;
1005 value = load_connection(art->cConnections, artList, CONN_DST_EG1_RELEASETIME);
1006 release = to_msec(value);
1007 if (release >= 20)
1009 release = release / 20;
1012 value = load_connection(art->cConnections, artList, CONN_DST_EG1_SUSTAINLEVEL) * 2;
1013 sustain = (int)((1.0 - to_normalized_percent(value)) * 250.0);
1014 if (sustain < 0)
1016 sustain = 0;
1018 if (sustain > 255)
1020 sustain = 250;
1023 value = load_connection(art->cConnections, artList, CONN_DST_PAN) / 2;
1024 int panval = (int)((0.5 + to_normalized_percent(value)) * 127.0);
1025 if (panval < 0) panval = 0; else if (panval > 127) panval = 127;
1026 sample->panning = panval;
1028 //ctl->cmsg(CMSG_INFO, VERB_NORMAL,
1029 // "%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);
1031 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);
1034 sample->envelope_offset[ATTACK] = to_offset(255);
1035 sample->envelope_rate[ATTACK] = calc_rate(song, 255, sample->sample_rate, attack);
1037 sample->envelope_offset[HOLD] = to_offset(250);
1038 sample->envelope_rate[HOLD] = calc_rate(song, 5, sample->sample_rate, hold);
1040 sample->envelope_offset[DECAY] = to_offset(sustain);
1041 sample->envelope_rate[DECAY] = calc_rate(song, 255 - sustain, sample->sample_rate, decay);
1043 sample->envelope_offset[RELEASE] = to_offset(0);
1044 sample->envelope_rate[RELEASE] = calc_rate(song, 5 + sustain, sample->sample_rate, release);
1046 sample->envelope_offset[RELEASEB] = to_offset(0);
1047 sample->envelope_rate[RELEASEB] = to_offset(1);
1049 sample->envelope_offset[RELEASEC] = to_offset(0);
1050 sample->envelope_rate[RELEASEC] = to_offset(1);
1052 sample->modes |= MODES_ENVELOPE;
1055 sample->data_length <<= FRACTION_BITS;
1056 sample->loop_start <<= FRACTION_BITS;
1057 sample->loop_end <<= FRACTION_BITS;
1060 Instrument* load_instrument_dls(MidiSong *song, int drum, int bank, int instrument)
1062 Instrument *inst;
1063 uint32 i;
1064 DLS_Instrument *dls_ins;
1066 if (!song->patches)
1068 return(NULL);
1071 if (!drum)
1073 for (i = 0; i < song->patches->cInstruments; ++i)
1075 dls_ins = &song->patches->instruments[i];
1077 if (!(dls_ins->header->Locale.ulBank & 0x80000000) &&
1078 ((dls_ins->header->Locale.ulBank >> 8) & 0xFF) == bank &&
1079 dls_ins->header->Locale.ulInstrument == instrument)
1081 break;
1085 if (i == song->patches->cInstruments && !bank)
1087 for (i = 0; i < song->patches->cInstruments; ++i)
1089 dls_ins = &song->patches->instruments[i];
1091 if (!(dls_ins->header->Locale.ulBank & 0x80000000) &&
1092 dls_ins->header->Locale.ulInstrument == instrument)
1094 break;
1099 if (i == song->patches->cInstruments)
1101 ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Couldn't find melodic instrument %d in bank %d\n", instrument, bank);
1102 return(NULL);
1104 inst = (Instrument *)safe_malloc(sizeof(*inst));
1105 inst->type = INST_DLS;
1106 inst->samples = dls_ins->header->cRegions;
1107 inst->sample = (Sample *)safe_malloc(inst->samples * sizeof(*inst->sample));
1108 memset(inst->sample, 0, inst->samples * sizeof(*inst->sample));
1110 for (i = 0; i < dls_ins->header->cRegions; ++i)
1112 load_region_dls(song, song->patches, &inst->sample[i], dls_ins, i);
1115 else
1117 for (i = 0; i < song->patches->cInstruments; ++i)
1119 dls_ins = &song->patches->instruments[i];
1121 if ((dls_ins->header->Locale.ulBank & 0x80000000) &&
1122 dls_ins->header->Locale.ulInstrument == bank)
1124 break;
1128 if (i == song->patches->cInstruments && !bank)
1130 for (i = 0; i < song->patches->cInstruments; ++i)
1132 dls_ins = &song->patches->instruments[i];
1134 if ((dls_ins->header->Locale.ulBank & 0x80000000) &&
1135 dls_ins->header->Locale.ulInstrument == 0)
1137 break;
1142 if (i == song->patches->cInstruments)
1144 ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Couldn't find drum instrument %d\n", bank);
1145 return(NULL);
1147 int drum_reg = -1;
1149 for (i = 0; i < dls_ins->header->cRegions; i++)
1151 if (dls_ins->regions[i].header->RangeKey.usLow == instrument)
1153 drum_reg = i;
1154 break;
1158 if (drum_reg == -1)
1160 ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Couldn't find drum note %d\n", instrument);
1161 return(NULL);
1164 inst = (Instrument *)safe_malloc(sizeof(*inst));
1165 inst->type = INST_DLS;
1166 inst->samples = 1;
1167 inst->sample = (Sample *)safe_malloc(inst->samples * sizeof(*inst->sample));
1168 memset(inst->sample, 0, inst->samples * sizeof(*inst->sample));
1169 load_region_dls(song, song->patches, &inst->sample[0], dls_ins, drum_reg);
1172 return inst;