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(®ions, 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 = ®ion[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 = ®ion[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 = ®ion[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