1 /*---------------------------------------------------------------------------*
2   Project:  DLS converter for SYN
3   File:     dls.c
4 
5   Copyright (C)2001-2006 Nintendo  All Rights Reserved.
6 
7   These coded instructions, statements, and computer programs contain
8   proprietary information of Nintendo of America Inc. and/or Nintendo
9   Company Ltd., and are protected by Federal copyright law.  They may
10   not be disclosed to third parties or copied or duplicated in any form,
11   in whole or in part, without the prior written consent of Nintendo.
12 
13   $Log: dls.c,v $
14   Revision 1.5  06/09/2006 07:55:31  aka
15   Removed temporary workaround for SDK1.0.
16 
17   Revision 1.4  03/16/2006 00:27:19  aka
18   Added temporary workaround for SDK1.0.
19 
20   Revision 1.3  02/08/2006 06:21:14  aka
21   Changed copyright.
22 
23   Revision 1.2  11/04/2005 07:16:48  aka
24   Changed audio frame length from 5ms to 3ms.
25 
26  *---------------------------------------------------------------------------*/
27 
28 #include <windows.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <math.h>
32 #include "types.h"
33 #include "dls.h"
34 #include "wt.h"
35 #include "string.h"
36 #include "dspadpcm.h"
37 
38 /*--------------------------------------------------------------------------*/
39 static FILE *dlsFile;
40 static FILE *wtFile;
41 static FILE *pcmFile;
42 
43 /*--------------------------------------------------------------------------*/
44 static int      currentProgram;
45 static int      percussive;
46 
47 static WTINST   melodicInst[128];
48 static WTINST   percussiveInst[128];
49 
50 static u16      artIndex;
51 static WTART    art[0xFFFF];
52 static WTART    artTemp;
53 
54 static u16      regionIndex;
55 static WTREGION region[0xFFFF];
56 
57 static int      waveOffset;
58 static int      waveIndex;
59 static WTSAMPLE waveSample[0xFFFF];
60 
61 static u16      adpcmIndex;
62 static WTADPCM  adpcm[0xFFFF];
63 
64 static int      loopStart;
65 static int      loopLength;
66 static int      encodeAdpcm;
67 static int      convertTo16Bit;
68 static int      compression;
69 static int      returnFlag;
70 
71 #define         USER_MODE_USEFLAG   0   // use option flag (default)
72 #define         USER_MODE_ADPCM     1   // compress all to ADPCM
73 #define         USER_MODE_RAW       2   // all raw PCM
74 
75 #define         F_WSMP_NO_COMPRESSION 0x0002
76 
77 /*--------------------------------------------------------------------------*/
78 #define reverse_endian_16(a)(       \
79             ((a & 0xFF00) >> 8) |   \
80             ((a & 0x00FF) << 8))
81 
82 #define reverse_endian_32(a)(               \
83             ((a & 0xFF000000) >> 24)    |   \
84             ((a & 0x00FF0000) >> 8)     |   \
85             ((a & 0x0000FF00) << 8)     |   \
86             ((a & 0x000000FF) << 24))
87 
88 /*--------------------------------------------------------------------------*/
dls_skip_chunk(void)89 void dls_skip_chunk(void)
90 {
91     u32 count;
92 
93     fread(&count, 1, 4, dlsFile);
94 
95     // fix alignment
96     if (count % sizeof(u16))
97         count += 1;
98 
99     fseek(dlsFile, count, SEEK_CUR);
100 
101 //    printf("Skipping %d bytes\n", count);
102 }
103 
104 
105 /*--------------------------------------------------------------------------*/
dls_string(void)106 void dls_string(void)
107 {
108     u32 count;
109 
110     fread(&count, 1, 4, dlsFile);
111 
112     // fix alignment
113     if (count % sizeof(u16))
114         count += 1;
115 
116     while (count)
117     {
118         char ch;
119 
120         fread(&ch, 1, 1, dlsFile);
121 //        printf("%c", ch);
122 
123         count--;
124     }
125 
126 //    printf("\n");
127 }
128 
129 
130 /*--------------------------------------------------------------------------*/
dls_riff(void)131 void dls_riff(void)
132 {
133     u32 count;
134 
135     fread(&count, 1, 4, dlsFile);
136 
137     printf("%d bytes\n", count);
138 }
139 
140 
141 /*--------------------------------------------------------------------------*/
dls_colh(void)142 void dls_colh(void)
143 {
144     u32 count, length;
145 
146     fread(&length, 1, 4, dlsFile);
147     fread(&count, 1, 4, dlsFile);
148 
149     // check to see if we have advanced the read position by specified length
150     length -= 4;
151 
152     if (length)
153         fseek(dlsFile, length, SEEK_CUR);
154 
155     printf("%d instruments\n", count);
156 }
157 
158 
159 /*--------------------------------------------------------------------------*/
dls_vers(void)160 void dls_vers(void)
161 {
162     u32 ms, ls, length;
163 
164     fread(&length, 1, 4, dlsFile);
165     fread(&ms, 1, 4, dlsFile);
166     fread(&ls, 1, 4, dlsFile);
167 
168     // check to see if we have advanced the read position by specified length
169     length -= 8;
170 
171     if (length)
172         fseek(dlsFile, length, SEEK_CUR);
173 
174     printf(
175         "VERSION %d,%d,%d,%d\n",
176         ms >> 16,
177         ms & 0xFFFF,
178         ls >> 16,
179         ls & 0xFFFF
180         );
181 }
182 
183 
184 
185 
186 /*--------------------------------------------------------------------------*/
dls_list(void)187 void dls_list(void)
188 {
189     u32 list, length;
190 
191     fread(&length, 1, 4, dlsFile);
192     fread(&list, 1, 4, dlsFile);
193 /*
194     printf(
195         "<%c%c%c%c>\n",
196         (list & 0xFF),
197         ((list >> 8) & 0xFF),
198         ((list >> 16) & 0xFF),
199         ((list >> 24) & 0xFF)
200         );
201 */
202     switch (list)
203     {
204     case COLH:
205     case VERS:
206     case LINS:
207     case INS:
208     case INSH:
209     case LRGN:
210     case RGN:
211     case RGNH:
212     case WSMP:
213     case WLNK:
214     case LART:
215     case LAR2:  // another Direct Music Producer hack!!! does it ever end?
216                 // if we don't do this we lose the articulations
217     case ART1:
218     case DATA:
219     case PTBL:
220     case DLID:
221     case WVPL:
222     case WAVE:
223     case WAVU:
224     case FMT:
225     case SMPL:
226     case INFO:
227 
228         break;
229 
230     default:
231 
232         printf(
233             "\n%cWarning: LIST \"%c%c%c%c\" not defined by DLS 1.0 spec. skipping chunk!\n",
234             7,
235             (list & 0xFF),
236             ((list >> 8) & 0xFF),
237             ((list >> 16) & 0xFF),
238             ((list >> 24) & 0xFF)
239             );
240 
241         fseek(dlsFile, length - 4, SEEK_CUR);
242     }
243 }
244 
245 
246 /*--------------------------------------------------------------------------*/
dls_insh(void)247 void dls_insh(void)
248 {
249     u32 regions;
250     u32 bank;
251     u32 program;
252     u32 length;
253 
254     fread(&length, 1, 4, dlsFile);
255     fread(&regions, 1, 4, dlsFile);
256     fread(&bank, 1, 4, dlsFile);
257     fread(&program, 1, 4, dlsFile);
258 
259     // check to see if we have advanced the read position by specified length
260     length -= 12;
261 
262     if (length)
263         fseek(dlsFile, length, SEEK_CUR);
264 
265 
266 //    printf("%d regions, bank: %d, program: %d\n", regions, bank, program);
267 
268     if (bank & 0x80000000)  // percussive instrument
269         percussive = 1;
270     else
271         percussive = 0;
272 
273     // this wt format does not support banks so if the instrument is not on
274     // bank 0 do not make any instrument reference to it
275     if (bank & 0x0000FFFF)
276         currentProgram = 0xFFFFFFFF;
277     else
278         currentProgram = program;
279 }
280 
281 
282 /*--------------------------------------------------------------------------*/
dls_rgnh(void)283 void dls_rgnh(void)
284 {
285     u16         loKey;
286     u16         hiKey;
287     u16         loVel;
288     u16         hiVel;
289     u16         options;
290     u16         keyGroup;
291     WTREGION    *thisRegion;
292     u32         length;
293 
294     fread(&length, 1, 4, dlsFile);
295     fread(&loKey, 1, 2, dlsFile);
296     fread(&hiKey, 1, 2, dlsFile);
297     fread(&loVel, 1, 2, dlsFile);
298     fread(&hiVel, 1, 2, dlsFile);
299     fread(&options, 1, 2, dlsFile);
300     fread(&keyGroup, 1, 2, dlsFile);
301 /*
302     printf("loKey: %d, hiKey: %d\n", loKey, hiKey);
303     printf("loVel: %d, hiVel: %d\n", loVel, hiVel);
304     printf("Options: 0x%.4x\n", options);
305     printf("KeyGroup: %d\n", keyGroup);
306 */
307 
308     // check to see if we have advanced the read position by specified length
309     length -= 12;
310 
311     if (length)
312         fseek(dlsFile, length, SEEK_CUR);
313 
314     thisRegion = &region[regionIndex];
315 
316 //    thisRegion->loKey       = (u8)loKey;
317 //    thisRegion->hiKey       = (u8)hiKey;
318 //    thisRegion->loVel       = (u8)loVel;
319 //    thisRegion->hiVel       = (u8)hiVel;
320     thisRegion->keyGroup    = (u8)keyGroup;
321 
322     // mark the current instrument's keys for this region
323     if (currentProgram != 0xFFFFFFFF)
324     {
325         if (percussive)
326         {
327             int i;
328 
329             for (i = loKey; i <= hiKey; i++)
330             {
331                 if (percussiveInst[currentProgram].keyRegion[i] == 0xFFFF)
332                     percussiveInst[currentProgram].keyRegion[i] =
333                         reverse_endian_16(regionIndex);
334             }
335         }
336         else
337         {
338             int i;
339 
340             for (i = loKey; i <= hiKey; i++)
341             {
342                 if (melodicInst[currentProgram].keyRegion[i] == 0xFFFF)
343                     melodicInst[currentProgram].keyRegion[i] =
344                         reverse_endian_16(regionIndex);
345             }
346         }
347     }
348 }
349 
350 
351 /*--------------------------------------------------------------------------*/
dls_wsmp(void)352 void dls_wsmp(void)
353 {
354     u32         structSize;
355     u16         unityNote;
356     s16         fineTune;
357     s32         attenuation;
358     u32         options;
359     u32         loops;
360 
361     u32         size;
362     u32         type;
363     u32         start;
364     u32         length;
365 
366     WTREGION    *thisRegion;
367 
368     fseek(dlsFile, 4, SEEK_CUR);
369     fread(&structSize, 1, 4, dlsFile);
370     fread(&unityNote, 1, 2, dlsFile);
371     fread(&fineTune, 1, 2, dlsFile);
372     fread(&attenuation, 1, 4, dlsFile);
373     fread(&options, 1, 4, dlsFile);
374     fread(&loops, 1, 4, dlsFile);
375 
376 /*
377     printf("Struct size: %d\n", structSize);
378     printf("unityNote: %d\n", unityNote);
379     printf("fineTune: 0x%.4x\n", fineTune);
380     printf("Attenuation: 0x%.8x\n", attenuation);
381     printf("Options: 0x%.8x\n", options);
382     printf("Loops: %d\n", loops);
383 */
384 
385     thisRegion = &region[regionIndex];
386 
387     thisRegion->unityNote   = (u8)unityNote;
388 
389     thisRegion->fineTune    = reverse_endian_16(fineTune);
390     thisRegion->attn        = reverse_endian_32(attenuation);
391 
392     if (loops)
393     {
394         fread(&size, 1, 4, dlsFile);
395         fread(&type, 1, 4, dlsFile);
396         fread(&start, 1, 4, dlsFile);
397         fread(&length, 1, 4, dlsFile);
398         /*
399         printf("\n");
400         printf("region: %d\n", regionIndex);
401         printf("size: %d\n", size);
402         printf("type: 0x%.8x\n", type);
403         printf("start: %d\n", start);
404         printf("length: %d\n", length);
405         */
406         thisRegion->loopStart   = reverse_endian_32(start);
407         thisRegion->loopLength  = reverse_endian_32(length);
408         loopStart   = start;
409         loopLength  = length;
410     }
411     else
412     {
413         thisRegion->loopStart   = 0;
414         thisRegion->loopLength  = 0;
415         loopStart   = 0;
416         loopLength  = 0;
417     }
418 
419     switch (compression)
420     {
421     case MODE_USE_FLAG: // use F_WSMP_NO_COMPRESSION flag
422 
423         if (options & F_WSMP_NO_COMPRESSION)
424             encodeAdpcm = 0;
425         else
426             encodeAdpcm = 1;
427 
428         break;
429 
430     case MODE_COMPRESS_ALL:
431 
432         encodeAdpcm = 1;
433 
434         break;
435 
436     case MODE_COMPRESS_NONE:
437 
438         encodeAdpcm = 0;
439 
440         break;
441     }
442 }
443 
444 
445 /*--------------------------------------------------------------------------*/
dls_wlnk(void)446 void dls_wlnk(void)
447 {
448     u16         options;
449     u16         phaseGroup;
450     u32         channel;
451     u32         tableIndex;
452     WTREGION    *thisRegion;
453 
454     fseek(dlsFile, 4, SEEK_CUR);
455     fread(&options, 1, 2, dlsFile);
456     fread(&phaseGroup, 1, 2, dlsFile);
457     fread(&channel, 1, 4, dlsFile);
458     fread(&tableIndex, 1, 4, dlsFile);
459 
460     /*
461     printf("Options: 0x%.4x\n", options);
462     printf("PhaseGroup: 0x%.4x\n", phaseGroup);
463     printf("Channel: %d\n", channel);
464     printf("TableIndex: %d\n", tableIndex);
465     */
466     thisRegion = &region[regionIndex];
467 
468     thisRegion->sampleIndex         = reverse_endian_32(tableIndex);
469     thisRegion->articulationIndex   = reverse_endian_32(artIndex);
470 
471     regionIndex++;
472 }
473 
474 
475 /*--------------------------------------------------------------------------*/
dls_art_default(void)476 void dls_art_default(void)
477 {
478     WTART *a = &artTemp;
479 
480     a->lfoFreq          = 0xFCACAE9C;       // 5Hz
481     a->lfoDelay         = 0xE0DB6022;       // 0.01 sec
482     a->lfoAtten         = 0x00000000;       // 0dB
483     a->lfoPitch         = 0x00000000;       // 0 cents
484     a->lfoMod2Atten     = 0x00000000;       // 0dB
485     a->lfoMod2Pitch     = 0x00000000;       // 0 cents
486 
487     a->eg1Attack        = 0x80000000;       // 0 seconds
488     a->eg1Decay         = 0x80000000;       // 0 seconds
489     a->eg1Sustain       = 0x03E80000;       // 100%
490     a->eg1Release       = 0x80000000;       // 0 seconds
491     a->eg1Vel2Attack    = 0x80000000;       // 0 seconds
492     a->eg1Key2Decay     = 0x80000000;       // 0 seconds
493 
494     a->eg2Attack        = 0x80000000;       // 0 seconds
495     a->eg2Decay         = 0x80000000;       // 0 seconds
496     a->eg2Sustain       = 0x03E80000;       // 100%
497     a->eg2Release       = 0x80000000;       // 0 seconds
498     a->eg2Vel2Attack    = 0x80000000;       // 0 seconds
499     a->eg2Key2Decay     = 0x80000000;       // 0 seconds
500     a->eg2Pitch         = 0x00000000;       // 0 cents
501 
502     a->pan              = 0x00000000;       // center
503 }
504 
505 
506 /*---------------------------------------------------------------------------*/
dls_connection(u16 source,u16 control,u16 destination,s32 scale)507 void dls_connection (u16 source, u16 control, u16 destination, s32 scale)
508 {
509     WTART *a = &artTemp;
510 
511     switch (source)
512         {
513         case CONN_SRC_NONE:
514 
515                 switch (destination)
516                 {
517                 case CONN_DST_LFO_FREQUENCY:    a->lfoFreq      = scale;    break;
518                 case CONN_DST_LFO_STARTDELAY:   a->lfoDelay     = scale;    break;
519                 case CONN_DST_EG1_ATTACKTIME:   a->eg1Attack    = scale;    break;
520                 case CONN_DST_EG1_DECAYTIME:    a->eg1Decay     = scale;    break;
521                 case CONN_DST_EG1_SUSTAINLEVEL: a->eg1Sustain   = scale;    break;
522                 case CONN_DST_EG1_RELEASETIME:  a->eg1Release   = scale;    break;
523                 case CONN_DST_EG2_ATTACKTIME:   a->eg2Attack    = scale;    break;
524                 case CONN_DST_EG2_DECAYTIME:    a->eg2Decay     = scale;    break;
525                 case CONN_DST_EG2_SUSTAINLEVEL: a->eg2Sustain   = scale;    break;
526                 case CONN_DST_EG2_RELEASETIME:  a->eg2Release   = scale;    break;
527                 case CONN_DST_EG1_RESERVED:                                 break;
528                 case CONN_DST_EG2_RESERVED:                                 break;
529                 case CONN_DST_PAN:              a->pan          = scale;    break;
530                 }
531 
532                 break;
533 
534         case CONN_SRC_LFO:
535 
536                 switch (destination)
537                 {
538                 case CONN_DST_ATTENUATION:
539 
540                         switch (control)
541                         {
542                         case CONN_SRC_NONE:         a->lfoAtten     = scale;    break;
543                         case CONN_SRC_CC1:                      a->lfoMod2Atten = scale;    break;
544                         }
545 
546                         break;
547 
548                 case CONN_DST_PITCH:
549 
550                         switch (control)
551                         {
552                         case CONN_SRC_NONE:         a->lfoPitch     = scale;    break;
553                         case CONN_SRC_CC1:                      a->lfoMod2Pitch = scale;    break;
554                         }
555 
556                         break;
557                 }
558 
559                 break;
560 
561         case CONN_SRC_KEYONVELOCITY:
562 
563                 switch (destination)
564                 {
565                 case CONN_DST_EG1_ATTACKTIME:   a->eg1Vel2Attack = scale;   break;
566                 case CONN_DST_EG2_ATTACKTIME:   a->eg2Vel2Attack = scale;   break;
567                 }
568 
569                 break;
570 
571         case CONN_SRC_KEYNUMBER:
572 
573                 switch (destination)
574                 {
575                 case CONN_DST_EG1_DECAYTIME:    a->eg1Key2Decay = scale;    break;
576                 case CONN_DST_EG2_DECAYTIME:    a->eg2Key2Decay = scale;    break;
577                 }
578 
579                 break;
580 
581         case CONN_SRC_EG2:
582 
583                 switch (destination)
584                 {
585                 case CONN_DST_PITCH:            a->eg2Pitch     = scale;    break;
586                 }
587 
588                 break;
589         }
590 }
591 
592 
593 /*---------------------------------------------------------------------------*/
dls_tc2ms(s32 scale)594 u32 dls_tc2ms(s32 scale)    // time cents to milliseconds
595 {
596         if (scale == 0x80000000)
597                 return 0;
598 
599     return (u32)(pow(2, (double)scale / (1200 * 65536)) * 1000);
600 }
601 
602 
603 /*--------------------------------------------------------------------------*/
dls_get_eg1Sustain(s32 scale)604 s32 dls_get_eg1Sustain(s32 scale)
605 {
606     f32 percent = (float)scale / 0x03E80000;
607 
608     return (s32)(0x03C00000 * percent) + 0xFC400000;
609 
610 /*
611     double dB;
612 
613     if (scale == 0x00000000)
614             dB = -96.0;
615         else
616             dB = -20.0 * log10(1000.0 / (scale / 0x00010000));
617 
618         return(s32)(dB * 10 * 0x00010000);
619 */
620 }
621 
622 
623 /*--------------------------------------------------------------------------*/
dls_get_eg1Release(s32 scale)624 s32 dls_get_eg1Release(s32 scale)
625 {
626     s32 frames;
627 
628         frames = dls_tc2ms(scale) / 3;  // 3 ms per audio frame
629 
630     if (frames)
631         return (s32)((-960 * 0x00010000) / frames);
632         else
633         return (s32)(-960 * 0x00010000);
634 }
635 
636 
637 /*--------------------------------------------------------------------------*/
dls_get_eg2Sustain(s32 scale,s32 cents)638 s32 dls_get_eg2Sustain(s32 scale, s32 cents)
639 {
640     if (scale == 0x00000000)
641         return 0;
642     else
643         return (s32)(cents * ((double)scale / (1000 * 65536)));
644 }
645 
646 
647 /*--------------------------------------------------------------------------*/
dls_get_eg2Release(s32 scale,s32 cents)648 s32 dls_get_eg2Release(s32 scale, s32 cents)
649 {
650     u32 frames;
651 
652         frames = dls_tc2ms(scale) / 3;  // 3 ms per audio frame
653 
654     if (frames)
655         return (s32)((cents * -1) / frames);
656         else
657         return cents * -1;
658 }
659 
660 
661 /*--------------------------------------------------------------------------*/
dls_get_lfoFreq(s32 scale)662 s32 dls_get_lfoFreq(s32 scale)
663 {
664     f32 f;
665 
666     f = (float)pow(2, ((double)scale / 65536 - 6900) / 1200) * 440;
667 
668     return (s32)(((1000.0f / f) / (3 * 64)) * 0x00010000); // 3ms frames * 64 steps in LFO
669 }
670 
671 
672 /*--------------------------------------------------------------------------*/
dls_get_lfoDelay(s32 scale)673 s32 dls_get_lfoDelay(s32 scale)
674 {
675     return dls_tc2ms(scale) / 65536;
676 }
677 
678 
679 /*--------------------------------------------------------------------------*/
dls_get_pan(s32 scale)680 s32 dls_get_pan(s32 scale)
681 {
682     if (scale == 0)
683         return 64;
684 
685     return (s32)(127 * ((float)(scale + (500 * 0x00010000)) / (1000 * 0x00010000))) ;
686 }
687 
688 
689 /*--------------------------------------------------------------------------*/
dls_set_art(void)690 void dls_set_art(void)
691 {
692     WTART *a = &art[artIndex];
693 
694     // print LFO
695     a->lfoFreq          = reverse_endian_32(dls_get_lfoFreq(artTemp.lfoFreq));
696     a->lfoDelay         = reverse_endian_32(dls_get_lfoDelay(artTemp.lfoDelay));
697     a->lfoAtten         = reverse_endian_32(artTemp.lfoAtten);
698     a->lfoPitch         = reverse_endian_32(artTemp.lfoPitch);
699     a->lfoMod2Atten     = reverse_endian_32(artTemp.lfoMod2Atten);
700     a->lfoMod2Pitch     = reverse_endian_32(artTemp.lfoMod2Pitch);
701 
702     // print (eg1) volume envelope
703     a->eg1Attack        = reverse_endian_32(artTemp.eg1Attack);
704     a->eg1Decay         = reverse_endian_32(artTemp.eg1Decay);
705     a->eg1Sustain       = reverse_endian_32(dls_get_eg1Sustain(artTemp.eg1Sustain));
706     a->eg1Release       = reverse_endian_32(dls_get_eg1Release(artTemp.eg1Release));
707     a->eg1Vel2Attack    = reverse_endian_32(artTemp.eg1Vel2Attack);
708     a->eg1Key2Decay     = reverse_endian_32(artTemp.eg1Key2Decay);
709 
710     // print (eg2) pitch envelope
711     a->eg2Pitch         = reverse_endian_32(artTemp.eg2Pitch);
712     a->eg2Attack        = reverse_endian_32(artTemp.eg2Attack);
713     a->eg2Decay         = reverse_endian_32(artTemp.eg2Decay);
714     a->eg2Sustain       = reverse_endian_32(dls_get_eg2Sustain(artTemp.eg2Sustain, artTemp.eg2Pitch));
715     a->eg2Release       = reverse_endian_32(dls_get_eg2Release(artTemp.eg2Release, artTemp.eg2Pitch));
716     a->eg2Vel2Attack    = reverse_endian_32(artTemp.eg2Vel2Attack);
717     a->eg2Key2Decay     = reverse_endian_32(artTemp.eg2Key2Decay);
718 
719     // print pan
720     a->pan              = reverse_endian_32(dls_get_pan(artTemp.pan));
721 }
722 
723 
724 /*--------------------------------------------------------------------------*/
dls_art1(void)725 void dls_art1(void)
726 {
727     u32 structSize;
728     u32 connectionBlocks;
729 
730     u16 source;
731     u16 control;
732     u16 destination;
733     u16 transform;
734     s32 scale;
735 
736     fseek(dlsFile, 4, SEEK_CUR);
737     fread(&structSize, 1, 4, dlsFile);
738     fread(&connectionBlocks, 1, 4, dlsFile);
739 /*
740     printf("StructSize: %d\n", structSize);
741     printf("ConnectionBlocks: %d", connectionBlocks);
742 */
743 
744     dls_art_default();
745 
746     while (connectionBlocks)
747     {
748         fread(&source, 1, 2, dlsFile);
749         fread(&control, 1, 2, dlsFile);
750         fread(&destination, 1, 2, dlsFile);
751         fread(&transform, 1, 2, dlsFile);
752         fread(&scale, 1, 4, dlsFile);
753 /*
754         printf("\n");
755         printf("Source: 0x%.4x\n", source);
756         printf("Control: 0x%.4x\n", control);
757         printf("Destination: 0x%.4x\n", destination);
758         printf("Transform: 0x%.4x\n", transform);
759         printf("Scale: 0x%.8x\n", scale);
760 */
761         dls_connection(source, control, destination, scale);
762 
763         connectionBlocks--;
764     }
765 
766     dls_set_art();
767     artIndex++;
768 }
769 
770 
771 /*--------------------------------------------------------------------------*/
dls_fmt(void)772 void dls_fmt(void)
773 {
774     u16 formatTag;
775     u16 channels;
776     u32 samplesPerSec;
777     u32 averageBytesPerSec;
778     u16 blockAlign;
779     u16 bitsPerSample;
780         u16 samplesPerSec16;
781     u16 format;
782 
783     fseek(dlsFile, 4, SEEK_CUR);
784     fread(&formatTag, 1, 2, dlsFile);
785     fread(&channels, 1, 2, dlsFile);
786     fread(&samplesPerSec, 1, 4, dlsFile);
787     fread(&averageBytesPerSec, 1, 4, dlsFile);
788     fread(&blockAlign, 1, 2, dlsFile);
789     fread(&bitsPerSample, 1, 2, dlsFile);
790     fseek(dlsFile, 2, SEEK_CUR);
791 /*
792     printf("FormatTag: 0x%.4x\n", formatTag);
793     printf("Channels: %d\n", channels);
794     printf("SamplesPerSec: %d\n", samplesPerSec);
795     printf("AverageBytesPerSec: %d\n", averageBytesPerSec);
796     printf("BlockAlign: %d\n", blockAlign);
797     printf("BitsPerSample: %d\n", bitsPerSample);
798 */
799     // give warning if format tag is not PCM
800     if (formatTag != 0x0001)
801         printf(
802             "Warning: sample %d is not in PCM format!%c\n",
803             waveIndex,
804             7
805             );
806 
807     switch (bitsPerSample)
808     {
809     case 16:
810 
811         if (encodeAdpcm)
812         {
813             format = WT_FORMAT_ADPCM;
814             convertTo16Bit = 0;
815         }
816         else
817         {
818             format = WT_FORMAT_PCM16;
819         }
820 
821         break;
822 
823     case 8:
824 
825         if (encodeAdpcm)
826         {
827             format = WT_FORMAT_ADPCM;
828             convertTo16Bit = 1;
829         }
830         else
831         {
832             format = WT_FORMAT_PCM8;
833         }
834 
835         break;
836 
837     default:
838 
839         printf(
840             "Warning: sample %d is not 16 or 8 bits per sample!%c\n",
841             waveIndex,
842             7
843             );
844     }
845 
846         samplesPerSec16 = (u16)samplesPerSec;
847     waveSample[waveIndex].format        = reverse_endian_16(format);
848     waveSample[waveIndex].sampleRate    = reverse_endian_16(samplesPerSec16);
849 }
850 
851 
852 /*--------------------------------------------------------------------------*/
853 typedef u32 (*lpFunc1)(u32);
854 typedef u32 (*lpFunc2)(void);
855 typedef void (*lpFunc3)(s16*, u8*, ADPCMINFO*, u32);
856 typedef void (*lpFunc4)(u8*, s16*, ADPCMINFO*, u32);
857 typedef void (*lpFunc5)(u8*, ADPCMINFO*, u32);
858 
859 extern lpFunc1 getBytesForAdpcmBuffer;
860 extern lpFunc1 getBytesForAdpcmSamples;
861 extern lpFunc1 getBytesForPcmBuffer;
862 extern lpFunc1 getNibbleAddress;
863 extern lpFunc2 getBytesForAdpcmInfo;
864 extern lpFunc3 encode;
865 extern lpFunc4 decode;
866 extern lpFunc5 getLoopContext;
867 
868 
dls_data(void)869 void dls_data(void)
870 {
871     u32 count;
872 
873     fread(&count, 1, 4, dlsFile);
874 
875     switch (reverse_endian_16(waveSample[waveIndex].format))
876     {
877     case WT_FORMAT_ADPCM:
878 
879         {
880             u8 bytes;
881 
882             // ADPCM has to start on a frame boundary (8 bytes)
883             bytes = waveOffset % 8;
884 
885             if (bytes)
886             {
887                 bytes = 8 - bytes;
888 
889                 while (bytes)
890                 {
891                     u8 ch = 0;
892                     fwrite(&ch, 1, 1, pcmFile);
893                     waveOffset++;
894                     bytes--;
895                 }
896             }
897 
898             // see if the sample needs to be converted to 16 bit first
899             if (convertTo16Bit)
900             {
901                 // allocate buffer for storage
902                 u8   *adpcmBuffer;
903                 void *pcm16Buffer;
904                 u32  nBytesForAdpcmBuffer;
905                 u32  nBytesForPcm16Buffer;
906                 u32  nBytesForAdpcmSamples;
907                 u32  temp;
908 
909                 nBytesForAdpcmBuffer     = getBytesForAdpcmBuffer(count);
910                 nBytesForPcm16Buffer     = getBytesForPcmBuffer(count);
911                 nBytesForAdpcmSamples    = getBytesForAdpcmSamples(count);
912 
913                 pcm16Buffer = malloc(nBytesForPcm16Buffer);
914                 adpcmBuffer = malloc(nBytesForAdpcmBuffer);
915 
916                 waveSample[waveIndex].length = reverse_endian_32(nBytesForAdpcmSamples);
917                 waveSample[waveIndex].offset = reverse_endian_32(waveOffset * 2);
918                 waveOffset += nBytesForAdpcmSamples;
919 
920                 if (pcm16Buffer && adpcmBuffer)
921                 {
922                     u16 *p;
923                     u32 samples;
924                     ADPCMINFO adpcminfo;
925 
926                     p = (s16*)pcm16Buffer;
927                     samples = count;
928 
929                     temp = samples;
930 
931                     while (samples)
932                     {
933                         u8  sample;
934 
935                         fread(&sample, 1, 1, dlsFile);
936                         *p++ = (s16)((sample + 0x80) << 8);
937 
938                         samples--;
939                     }
940 
941                     samples = temp;
942 
943                     encode(
944                         pcm16Buffer,
945                         adpcmBuffer,
946                         &adpcminfo,
947                         samples
948                         );
949 
950                     if (loopStart + loopLength)
951                         getLoopContext(
952                             adpcmBuffer,
953                             &adpcminfo,
954                             loopStart
955                             );
956 
957                     memcpy(&adpcm[adpcmIndex], &adpcminfo, sizeof(WTADPCM));
958 
959                     {
960                         u16 *p;
961 
962                         p = (u16*)&adpcm[adpcmIndex];
963 
964                         *p = reverse_endian_16(*p); p++;
965                         *p = reverse_endian_16(*p); p++;
966                         *p = reverse_endian_16(*p); p++;
967                         *p = reverse_endian_16(*p); p++;
968                         *p = reverse_endian_16(*p); p++;
969                         *p = reverse_endian_16(*p); p++;
970                         *p = reverse_endian_16(*p); p++;
971                         *p = reverse_endian_16(*p); p++;
972                         *p = reverse_endian_16(*p); p++;
973                         *p = reverse_endian_16(*p); p++;
974                         *p = reverse_endian_16(*p); p++;
975                         *p = reverse_endian_16(*p); p++;
976                         *p = reverse_endian_16(*p); p++;
977                         *p = reverse_endian_16(*p); p++;
978                         *p = reverse_endian_16(*p); p++;
979                         *p = reverse_endian_16(*p); p++;
980                         *p = reverse_endian_16(*p); p++;
981                         *p = reverse_endian_16(*p); p++;
982                         *p = reverse_endian_16(*p); p++;
983                         *p = reverse_endian_16(*p); p++;
984                         *p = reverse_endian_16(*p); p++;
985                         *p = reverse_endian_16(*p); p++;
986                         *p = reverse_endian_16(*p);
987                     }
988 
989                     fwrite(adpcmBuffer, nBytesForAdpcmSamples, 1, pcmFile);
990                 }
991                 else
992                 {
993                     printf(
994                         "Warning: could not allocate buffer for PCM conversion!\n%c",
995                         7
996                         );
997                 }
998 
999                 if (pcm16Buffer)    free(pcm16Buffer);
1000                 if (adpcmBuffer)    free(adpcmBuffer);
1001             }
1002             else
1003             {
1004                 u8  *adpcmBuffer;
1005                 s16 *pcmBuffer;
1006                 u32 samples;
1007                 u32 nBytesForBuffer, nBytesForSamples;
1008 
1009                 samples = count / 2;
1010 
1011                 nBytesForBuffer  = getBytesForAdpcmBuffer(samples);
1012                 nBytesForSamples = getBytesForAdpcmSamples(samples);
1013 
1014                 adpcmBuffer = malloc(nBytesForBuffer);
1015                 pcmBuffer   = malloc(count);
1016 
1017                 waveSample[waveIndex].length = reverse_endian_32(samples);
1018                 waveSample[waveIndex].offset = reverse_endian_32(waveOffset * 2);
1019                 waveOffset += nBytesForSamples;
1020 
1021                 if (adpcmBuffer && pcmBuffer)
1022                 {
1023                     ADPCMINFO adpcminfo;
1024 
1025                     fread(pcmBuffer, count, 1, dlsFile);
1026 
1027                     encode(
1028                         pcmBuffer,
1029                         adpcmBuffer,
1030                         &adpcminfo,
1031                         samples
1032                         );
1033 
1034                     if (loopStart + loopLength)
1035                         getLoopContext(
1036                             adpcmBuffer,
1037                             &adpcminfo,
1038                             loopStart
1039                             );
1040 
1041                     memcpy(&adpcm[adpcmIndex], &adpcminfo, sizeof(WTADPCM));
1042 
1043                     {
1044                         u16 *p;
1045 
1046                         p = (u16*)&adpcm[adpcmIndex];
1047 
1048                         *p = reverse_endian_16(*p); p++;
1049                         *p = reverse_endian_16(*p); p++;
1050                         *p = reverse_endian_16(*p); p++;
1051                         *p = reverse_endian_16(*p); p++;
1052                         *p = reverse_endian_16(*p); p++;
1053                         *p = reverse_endian_16(*p); p++;
1054                         *p = reverse_endian_16(*p); p++;
1055                         *p = reverse_endian_16(*p); p++;
1056                         *p = reverse_endian_16(*p); p++;
1057                         *p = reverse_endian_16(*p); p++;
1058                         *p = reverse_endian_16(*p); p++;
1059                         *p = reverse_endian_16(*p); p++;
1060                         *p = reverse_endian_16(*p); p++;
1061                         *p = reverse_endian_16(*p); p++;
1062                         *p = reverse_endian_16(*p); p++;
1063                         *p = reverse_endian_16(*p); p++;
1064                         *p = reverse_endian_16(*p); p++;
1065                         *p = reverse_endian_16(*p); p++;
1066                         *p = reverse_endian_16(*p); p++;
1067                         *p = reverse_endian_16(*p); p++;
1068                         *p = reverse_endian_16(*p); p++;
1069                         *p = reverse_endian_16(*p); p++;
1070                         *p = reverse_endian_16(*p);
1071                     }
1072 
1073                     fwrite(adpcmBuffer, nBytesForSamples, 1, pcmFile);
1074                 }
1075                 else
1076                 {
1077                     printf(
1078                         "Warning: could not allocate buffer for ADPCM encode!\n%c",
1079                         7
1080                         );
1081                 }
1082 
1083                 if (adpcmBuffer)    free(adpcmBuffer);
1084                 if (pcmBuffer)      free(pcmBuffer);
1085             }
1086         }
1087 
1088         waveSample[waveIndex].adpcmIndex = reverse_endian_16(adpcmIndex);
1089         adpcmIndex++;
1090 
1091         break;
1092 
1093     case WT_FORMAT_PCM16:
1094 
1095         waveSample[waveIndex].length = reverse_endian_32(count / 2);
1096         waveSample[waveIndex].offset = reverse_endian_32(waveOffset / 2);
1097         waveOffset += count;
1098 
1099         while (count)
1100         {
1101             u16 sample;
1102 
1103             fread(&sample, 1, 2, dlsFile);
1104             sample = reverse_endian_16(sample);
1105             fwrite(&sample, 1, 2, pcmFile);
1106 
1107             count -= 2;
1108         }
1109 
1110         break;
1111 
1112     case WT_FORMAT_PCM8:
1113 
1114         waveSample[waveIndex].length = reverse_endian_32(count);
1115         waveSample[waveIndex].offset = reverse_endian_32(waveOffset);
1116         waveOffset += count;
1117 
1118         while (count)
1119         {
1120             u8 sample;
1121 
1122             fread(&sample, 1, 1, dlsFile);
1123             sample += 0x80;
1124             fwrite(&sample, 1, 1, pcmFile);
1125 
1126             count--;
1127         }
1128 
1129         break;
1130     }
1131 
1132     waveIndex++;
1133     printf(".");
1134 }
1135 
1136 
1137 /*--------------------------------------------------------------------------*/
dls_read_file(FILE * dlsFile_,FILE * wtFile_,FILE * pcmFile_,int mode)1138 void dls_read_file(FILE *dlsFile_, FILE *wtFile_, FILE *pcmFile_, int mode)
1139 {
1140     WTFILEHEADER fileHeader;
1141     int filePosition;
1142     int i, j;
1143 
1144     // initialize file pointers
1145     dlsFile         = dlsFile_;
1146     wtFile          = wtFile_;
1147     pcmFile         = pcmFile_;
1148 
1149     artIndex        = 0;
1150     regionIndex     = 0;
1151     waveIndex       = 0;
1152     waveOffset      = 0;
1153     adpcmIndex      = 0;
1154 
1155     compression     = mode;
1156 
1157     // mark all instrument regions invalid
1158     for (i = 0; i < 128; i++)
1159         for (j = 0; j < 128; j++)
1160             percussiveInst[i].keyRegion[j] = 0xFFFF;
1161 
1162     for (i = 0; i < 128; i++)
1163         for (j = 0; j < 128; j++)
1164             melodicInst[i].keyRegion[j] = 0xFFFF;
1165 
1166         while (1)
1167         {
1168                 u32 chunk;
1169 
1170         if (fread(&chunk, 1, 4, dlsFile) == 0)
1171         {
1172             printf("\nEnd of DLS file reached\n");
1173             break;
1174         }
1175 /*
1176                 printf(
1177             "<%c%c%c%c>\n",
1178             (chunk & 0xFF),
1179             ((chunk >> 8) & 0xFF),
1180             ((chunk >> 16) & 0xFF),
1181             ((chunk >> 24) & 0xFF)
1182             );
1183 */
1184                 switch (chunk)
1185                 {
1186         case RIFF:  dls_riff(); break;
1187                 case COLH:  dls_colh(); break;
1188                 case VERS:  dls_vers(); break;
1189         case LIST:  dls_list(); break;
1190         case INSH:  dls_insh(); break;
1191         case RGNH:  dls_rgnh(); break;
1192         case WSMP:  dls_wsmp(); break;
1193         case WLNK:  dls_wlnk(); break;
1194         case ART1:  dls_art1(); break;
1195         case FMT:   dls_fmt();  break;
1196         case DATA:  dls_data(); break;
1197 
1198         case DLS:
1199 
1200                         break;
1201 
1202         case IARL:
1203         case IART:
1204         case ICMS:
1205         case ICMT:
1206         case ICOP:
1207         case ICRD:
1208         case IENG:
1209         case IGNR:
1210         case IKEY:
1211         case IMED:
1212         case INAM:
1213         case IPRD:
1214         case ISBJ:
1215         case ISFT:
1216         case ISRC:
1217         case ISRF:
1218         case ITCH:
1219 
1220             dls_string();
1221             break;
1222 
1223         case PTBL:
1224                 default:
1225 
1226             dls_skip_chunk();
1227 
1228                         break;
1229 
1230                 }
1231         }
1232 
1233     // write wt file
1234     fwrite(&fileHeader, sizeof(WTFILEHEADER), 1, wtFile);
1235 
1236     filePosition = sizeof(WTFILEHEADER);
1237     fileHeader.offsetPercussiveInst = reverse_endian_32(filePosition);
1238 
1239     fwrite(percussiveInst, sizeof(WTINST), 128, wtFile);
1240 
1241     filePosition += sizeof(WTINST) * 128;
1242     fileHeader.offsetMelodicInst    = reverse_endian_32(filePosition);
1243 
1244     fwrite(melodicInst, sizeof(WTINST), 128, wtFile);
1245 
1246     filePosition += sizeof(WTINST) * 128;
1247     fileHeader.offsetRegions        = reverse_endian_32(filePosition);
1248 
1249     fwrite(region, sizeof(WTREGION), regionIndex, wtFile);
1250 
1251     filePosition += sizeof(WTREGION) * regionIndex;
1252     fileHeader.offsetArticulations  = reverse_endian_32(filePosition);
1253 
1254     fwrite(art, sizeof(WTART), artIndex, wtFile);
1255 
1256     filePosition += sizeof(WTART) * artIndex;
1257     fileHeader.offsetSamples        = reverse_endian_32(filePosition);
1258 
1259     fwrite(waveSample, sizeof(WTSAMPLE), waveIndex, wtFile);
1260 
1261     filePosition += sizeof(WTSAMPLE) * waveIndex;
1262     fileHeader.offsetAdpcmContext   = reverse_endian_32(filePosition);
1263 
1264     fwrite(adpcm, sizeof(WTADPCM), adpcmIndex, wtFile);
1265 
1266     // write the real header again
1267     fseek(wtFile, 0, SEEK_SET);
1268     fwrite(&fileHeader, sizeof(WTFILEHEADER), 1, wtFile);
1269 }
1270