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, ®ion->wsmp, ®ion->wsmp_loop);
494 break;
495 case FOURCC_LART:
496 case FOURCC_LAR2:
497 Parse_lart(data, chunk, ®ion->art, ®ion->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