1 /* ______ ___ ___
2 * /\ _ \ /\_ \ /\_ \
3 * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___
4 * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\
5 * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \
6 * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
7 * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/
8 * /\____/
9 * \_/__/
10 *
11 * MIDI patch (for DIGMID) grabbing utility for the Allegro library.
12 *
13 * By Shawn Hargreaves.
14 *
15 * SoundFont loader based on code provided by George Foot.
16 *
17 * See readme.txt for copyright information.
18 */
19
20
21 #define ALLEGRO_USE_CONSOLE
22
23 #include <stdio.h>
24 #include <string.h>
25 #include <time.h>
26 #include <math.h>
27
28 #include "allegro.h"
29 #include "allegro/internal/aintern.h"
30 #include "datedit.h"
31
32
33
34 static DATAFILE *datafile = NULL;
35
36 static int err = 0;
37
38 static int opt_compression = 0;
39 static int opt_overwrite = FALSE;
40 static int opt_8bit = FALSE;
41 static int opt_verbose = FALSE;
42 static int opt_veryverbose = FALSE;
43 static int opt_bank = 0;
44 static int opt_drum_bank = 0;
45 static char *opt_datafile = NULL;
46 static char *opt_configfile = NULL;
47 static char *opt_soundfont = NULL;
48
49 #define MAX_FILES 256
50
51 static char *opt_namelist[MAX_FILES];
52 static int opt_numnames = 0;
53
54 static int need_patches[128], need_drums[128];
55
56
57
58 static char *patch_names[] =
59 {
60 "Acoustic Grand", "Bright Acoustic",
61 "Electric Grand", "Honky-Tonk",
62 "Electric Piano 1", "Electric Piano 2",
63 "Harpsichord", "Clav",
64 "Celesta", "Glockenspiel",
65 "Music Box", "Vibraphone",
66 "Marimba", "Xylophone",
67 "Tubular Bells", "Dulcimer",
68 "Drawbar Organ", "Percussive Organ",
69 "Rock Organ", "Church Organ",
70 "Reed Organ", "Accoridan",
71 "Harmonica", "Tango Accordian",
72 "Acoustic Guitar (nylon)", "Acoustic Guitar (steel)",
73 "Electric Guitar (jazz)", "Electric Guitar (clean)",
74 "Electric Guitar (muted)", "Overdriven Guitar",
75 "Distortion Guitar", "Guitar Harmonics",
76 "Acoustic Bass", "Electric Bass (finger)",
77 "Electric Bass (pick)", "Fretless Bass",
78 "Slap Bass 1", "Slap Bass 2",
79 "Synth Bass 1", "Synth Bass 2",
80 "Violin", "Viola",
81 "Cello", "Contrabass",
82 "Tremolo Strings", "Pizzicato Strings",
83 "Orchestral Strings", "Timpani",
84 "String Ensemble 1", "String Ensemble 2",
85 "SynthStrings 1", "SynthStrings 2",
86 "Choir Aahs", "Voice Oohs",
87 "Synth Voice", "Orchestra Hit",
88 "Trumpet", "Trombone",
89 "Tuba", "Muted Trumpet",
90 "French Horn", "Brass Section",
91 "SynthBrass 1", "SynthBrass 2",
92 "Soprano Sax", "Alto Sax",
93 "Tenor Sax", "Baritone Sax",
94 "Oboe", "English Horn",
95 "Bassoon", "Clarinet",
96 "Piccolo", "Flute",
97 "Recorder", "Pan Flute",
98 "Blown Bottle", "Skakuhachi",
99 "Whistle", "Ocarina",
100 "Lead 1 (square)", "Lead 2 (sawtooth)",
101 "Lead 3 (calliope)", "Lead 4 (chiff)",
102 "Lead 5 (charang)", "Lead 6 (voice)",
103 "Lead 7 (fifths)", "Lead 8 (bass+lead)",
104 "Pad 1 (new age)", "Pad 2 (warm)",
105 "Pad 3 (polysynth)", "Pad 4 (choir)",
106 "Pad 5 (bowed)", "Pad 6 (metallic)",
107 "Pad 7 (halo)", "Pad 8 (sweep)",
108 "FX 1 (rain)", "FX 2 (soundtrack)",
109 "FX 3 (crystal)", "FX 4 (atmosphere)",
110 "FX 5 (brightness)", "FX 6 (goblins)",
111 "FX 7 (echoes)", "FX 8 (sci-fi)",
112 "Sitar", "Banjo",
113 "Shamisen", "Koto",
114 "Kalimba", "Bagpipe",
115 "Fiddle", "Shanai",
116 "Tinkle Bell", "Agogo",
117 "Steel Drums", "Woodblock",
118 "Taiko Drum", "Melodic Tom",
119 "Synth Drum", "Reverse Cymbal",
120 "Guitar Fret Noise", "Breath Noise",
121 "Seashore", "Bird Tweet",
122 "Telephone ring", "Helicopter",
123 "Applause", "Gunshot"
124 };
125
126
127
128 static char *drum_names[] =
129 {
130 "Acoustic Bass Drum", "Bass Drum 1",
131 "Side Stick", "Acoustic Snare",
132 "Hand Clap", "Electric Snare",
133 "Low Floor Tom", "Closed Hi-Hat",
134 "High Floor Tom", "Pedal Hi-Hat",
135 "Low Tom", "Open Hi-Hat",
136 "Low-Mid Tom", "Hi-Mid Tom",
137 "Crash Cymbal 1", "High Tom",
138 "Ride Cymbal 1", "Chinese Cymbal",
139 "Ride Bell", "Tambourine",
140 "Splash Cymbal", "Cowbell",
141 "Crash Cymbal 2", "Vibraslap",
142 "Ride Cymbal 2", "Hi Bongo",
143 "Low Bongo", "Mute Hi Conga",
144 "Open Hi Conga", "Low Conga",
145 "High Timbale", "Low Timbale",
146 "High Agogo", "Low Agogo",
147 "Cabasa", "Maracas",
148 "Short Whistle", "Long Whistle",
149 "Short Guiro", "Long Guiro",
150 "Claves", "Hi Wood Block",
151 "Low Wood Block", "Mute Cuica",
152 "Open Cuica", "Mute Triangle",
153 "Open Triangle"
154 };
155
156
157
158 static char *short_patch_names[] =
159 {
160 "acpiano", "brpiano", "synpiano", "honktonk",
161 "epiano1", "epiano2", "hrpsi", "clavi",
162 "celeste", "glock", "musicbox", "vibes",
163 "marimba", "xylo", "tubebell", "dulcimer",
164 "drawbar", "percorg", "rockorg", "church",
165 "reedorg", "tango", "harmonca", "concert",
166 "nylongtr", "steelgtr", "jazzgtr", "cleangtr",
167 "mutegtr", "drivegtr", "distgtr", "harmgtr",
168 "acbass", "fngrbass", "pickbass", "fretless",
169 "slapbas1", "slapbas2", "synbass1", "synbass2",
170 "violin", "viola", "cello", "contra",
171 "tremstr", "pizz", "harp", "timp",
172 "strens1", "strens2", "synstr1", "synstr2",
173 "choirah", "choiroh", "synchoir", "orchhit",
174 "trumpet", "trombone", "tuba", "mutetrpt",
175 "horn", "brassens", "synbras1", "synbras2",
176 "sopsax", "altosax", "tenorsax", "barisax",
177 "oboe", "englhorn", "bassoon", "clarinet",
178 "piccolo", "flute", "recorder", "panflute",
179 "bottle", "shaku", "whistle", "ocarina",
180 "square", "saw", "calliope", "chiff",
181 "charang", "voice", "fifths", "basslead",
182 "newage", "warm", "polysyn", "choir",
183 "bowed", "metal", "halo", "sweep",
184 "rain", "sndtrack", "crystal", "atmos",
185 "bright", "goblins", "echoes", "scifi",
186 "sitar", "banjo", "shamisen", "koto",
187 "kalimba", "bagpipes", "fiddle", "shannai",
188 "tinkle", "agogo", "steel", "woodblck",
189 "taiko", "toms", "syndrum", "reverse",
190 "fret", "blow", "seashore", "birds",
191 "phone", "copter", "applause", "gunshot"
192 };
193
194
195
196 static char *short_drum_names[] =
197 {
198 "kick1", "kick2", "rimshot", "snare1",
199 "handclap", "snare2", "tomflrlo", "hihatcl",
200 "tomflrhi", "hihatpd", "tomlow", "hihatop",
201 "tommidlo", "tommidhi", "crash1", "tomhi",
202 "ride1", "chinese", "ridebell", "tambrine",
203 "splash", "cowbell", "crash2", "vibrslap",
204 "ride2", "bongohi", "bongolo", "congamt",
205 "congahi", "congalo", "timbalhi", "timballo",
206 "agogohi", "agogolo", "cabasa", "maracas",
207 "whistle1", "whistle2", "guiro1", "guiro2",
208 "claves", "woodhi", "woodlo", "cuica1",
209 "cuica2", "triangl1", "triangl2"
210 };
211
212
213
214 /* display help on the command syntax */
usage(void)215 static void usage(void)
216 {
217 printf("\nPatch grabber for the Allegro DIGMID driver " ALLEGRO_VERSION_STR ", " ALLEGRO_PLATFORM_STR "\n");
218 printf("By Shawn Hargreaves, " ALLEGRO_DATE_STR "\n\n");
219 printf("Usage: pat2dat [options] filename.dat [samplelocation] [tunes.mid]\n\n");
220 printf("Supported input formats:\n");
221 printf("\tGUS patch: <location> should point to the default.cfg index file\n");
222 printf("\tSoundFont: <location> should point to a SoundFont .sf2 file\n\n");
223 printf("Options:\n");
224 printf("\t'-b x' grab specified instrument bank\n");
225 printf("\t'-c' compress objects\n");
226 printf("\t'-d x' grab specified percussion kit\n");
227 printf("\t'-o' overwrite existing datafile\n");
228 printf("\t'-v' select verbose mode\n");
229 printf("\t'-vv' select very verbose mode\n");
230 printf("\t'-8' reduce sample data to 8 bits\n");
231 }
232
233
234
235 /* unused callback for datedit.c */
datedit_ask(AL_CONST char * fmt,...)236 int datedit_ask(AL_CONST char *fmt, ...) { return 0; }
237
238 /* unused callback for datedit.c */
datedit_select(AL_CONST char * (* list_getter)(int index,int * list_size),AL_CONST char * fmt,...)239 int datedit_select(AL_CONST char *(*list_getter)(int index, int *list_size), AL_CONST char *fmt, ...) { return 0; }
240
241
242 /* callback for outputting messages */
datedit_msg(AL_CONST char * fmt,...)243 void datedit_msg(AL_CONST char *fmt, ...)
244 {
245 va_list args;
246 char buf[1024];
247
248 va_start(args, fmt);
249 vsprintf(buf, fmt, args);
250 va_end(args);
251
252 printf("%s\n", buf);
253 }
254
255
256
257 /* callback for starting a 2-part message output */
datedit_startmsg(AL_CONST char * fmt,...)258 void datedit_startmsg(AL_CONST char *fmt, ...)
259 {
260 va_list args;
261 char buf[1024];
262
263 va_start(args, fmt);
264 vsprintf(buf, fmt, args);
265 va_end(args);
266
267 printf("%s", buf);
268 fflush(stdout);
269 }
270
271
272
273 /* callback for ending a 2-part message output */
datedit_endmsg(AL_CONST char * fmt,...)274 void datedit_endmsg(AL_CONST char *fmt, ...)
275 {
276 va_list args;
277 char buf[1024];
278
279 va_start(args, fmt);
280 vsprintf(buf, fmt, args);
281 va_end(args);
282
283 printf("%s\n", buf);
284 }
285
286
287
288 /* callback for printing errors */
datedit_error(AL_CONST char * fmt,...)289 void datedit_error(AL_CONST char *fmt, ...)
290 {
291 va_list args;
292 char buf[1024];
293
294 va_start(args, fmt);
295 vsprintf(buf, fmt, args);
296 va_end(args);
297
298 fprintf(stderr, "%s\n", buf);
299
300 err = 1;
301 }
302
303
304
305 /* deal with the strange variable length MIDI number format */
parse_var_len(unsigned char ** data)306 static unsigned long parse_var_len(unsigned char **data)
307 {
308 unsigned long val = **data & 0x7F;
309
310 while (**data & 0x80) {
311 (*data)++;
312 val <<= 7;
313 val += (**data & 0x7F);
314 }
315
316 (*data)++;
317 return val;
318 }
319
320
321
322 /* scans through a MIDI file to find which patches it needs */
scan_patches(MIDI * midi,char * patches,char * drums)323 static void scan_patches(MIDI *midi, char *patches, char *drums)
324 {
325 unsigned char *p, *end;
326 unsigned char running_status, event;
327 long l;
328 int c;
329
330 for (c=0; c<128; c++) /* initialise to unused */
331 patches[c] = drums[c] = FALSE;
332
333 for (c=0; c<MIDI_TRACKS; c++) { /* for each track... */
334 p = midi->track[c].data;
335 end = p + midi->track[c].len;
336 running_status = 0;
337
338 while (p < end) { /* work through data stream */
339 event = *p;
340 if (event & 0x80) { /* regular message */
341 p++;
342 if ((event != 0xF0) && (event != 0xF7) && (event != 0xFF))
343 running_status = event;
344 }
345 else /* use running status */
346 event = running_status;
347
348 switch (event>>4) {
349
350 case 0x0C: /* program change! */
351 patches[*p] = TRUE;
352 p++;
353 break;
354
355 case 0x09: /* note on, is it a drum? */
356 if ((event & 0x0F) == 9)
357 drums[*p] = TRUE;
358 p += 2;
359 break;
360
361 case 0x08: /* note off */
362 case 0x0A: /* note aftertouch */
363 case 0x0B: /* control change */
364 case 0x0E: /* pitch bend */
365 p += 2;
366 break;
367
368 case 0x0D: /* channel aftertouch */
369 p += 1;
370 break;
371
372 case 0x0F: /* special event */
373 switch (event) {
374 case 0xF0: /* sysex */
375 case 0xF7:
376 l = parse_var_len(&p);
377 p += l;
378 break;
379
380 case 0xF2: /* song position */
381 p += 2;
382 break;
383
384 case 0xF3: /* song select */
385 p++;
386 break;
387
388 case 0xFF: /* meta-event */
389 p++;
390 l = parse_var_len(&p);
391 p += l;
392 break;
393
394 default:
395 /* the other special events don't have any data bytes,
396 so we don't need to bother skipping past them */
397 break;
398 }
399 break;
400
401 default:
402 /* something has gone badly wrong if we ever get to here */
403 break;
404 }
405
406 if (p < end) /* skip time offset */
407 parse_var_len(&p);
408 }
409 }
410 }
411
412
413
414 /* reads a MIDI file to see what patches it requires */
read_midi(AL_CONST char * filename,int attrib,void * param)415 static int read_midi(AL_CONST char *filename, int attrib, void *param)
416 {
417 char patches[128], drums[128];
418 char fname[256];
419 MIDI *midi;
420 int c;
421
422 strcpy(fname, filename);
423 fix_filename_case(fname);
424
425 printf("Scanning %s...\n", fname);
426
427 midi = load_midi(fname);
428 if (!midi) {
429 fprintf(stderr, "Error reading %s\n", fname);
430 err = 1;
431 return -1;
432 }
433
434 scan_patches(midi, patches, drums);
435
436 if (opt_veryverbose) {
437 printf("\n\tUses patches:\n");
438
439 for (c=0; c<128; c++)
440 if (patches[c])
441 printf("\t\t%c Instrument #%-6d(%s)\n", (need_patches[c] ? ' ' : '*'), c+1, patch_names[c]);
442
443 for (c=0; c<128; c++)
444 if (drums[c])
445 printf("\t\t%c Percussion #%-6d(%s)\n", (need_drums[c] ? ' ' : '*'), c+1, (((c >= 35) && (c <= 81)) ? drum_names[c-35] : "unknown"));
446
447 printf("\n");
448 }
449
450 for (c=0; c<128; c++) {
451 if (patches[c])
452 need_patches[c] = TRUE;
453
454 if (drums[c])
455 need_drums[c] = TRUE;
456 }
457
458 destroy_midi(midi);
459 return 0;
460 }
461
462
463
464 /* scratch buffer for generating new patch files */
465 static unsigned char *mem = NULL;
466 static int mem_size = 0;
467 static int mem_alloced = 0;
468
469
470
471 /* writes a byte to the memory buffer */
mem_write8(int val)472 static void mem_write8(int val)
473 {
474 if (mem_size >= mem_alloced) {
475 mem_alloced += 4096;
476 mem = _AL_REALLOC(mem, mem_alloced);
477 }
478
479 mem[mem_size] = val;
480 mem_size++;
481 }
482
483
484
485 /* writes a word to the memory buffer (little endian) */
mem_write16(int val)486 static void mem_write16(int val)
487 {
488 mem_write8(val & 0xFF);
489 mem_write8((val >> 8) & 0xFF);
490 }
491
492
493
494 /* writes a long to the memory buffer (little endian) */
mem_write32(int val)495 static void mem_write32(int val)
496 {
497 mem_write8(val & 0xFF);
498 mem_write8((val >> 8) & 0xFF);
499 mem_write8((val >> 16) & 0xFF);
500 mem_write8((val >> 24) & 0xFF);
501 }
502
503
504
505 /* alters data already written to the memory buffer (little endian) */
mem_modify32(int pos,int val)506 static void mem_modify32(int pos, int val)
507 {
508 mem[pos] = val & 0xFF;
509 mem[pos+1] = (val >> 8) & 0xFF;
510 mem[pos+2] = (val >> 16) & 0xFF;
511 mem[pos+3] = (val >> 24) & 0xFF;
512 }
513
514
515
516 /* writes a block of data the memory buffer */
mem_write_block(void * data,int size)517 static void mem_write_block(void *data, int size)
518 {
519 if (mem_size+size > mem_alloced) {
520 mem_alloced = (mem_alloced + size + 4095) & ~4095;
521 mem = _AL_REALLOC(mem, mem_alloced);
522 }
523
524 memcpy(mem+mem_size, data, size);
525 mem_size += size;
526 }
527
528
529
530 /* writes from a file to the memory buffer */
mem_write_file(PACKFILE * f,int size)531 static void mem_write_file(PACKFILE *f, int size)
532 {
533 if (mem_size+size > mem_alloced) {
534 mem_alloced = (mem_alloced + size + 4095) & ~4095;
535 mem = _AL_REALLOC(mem, mem_alloced);
536 }
537
538 pack_fread(mem+mem_size, size, f);
539 mem_size += size;
540 }
541
542
543
544 /* imports data from a GUS patch file */
grab_patch(int type,AL_CONST char * filename,DATAFILE_PROPERTY ** prop,int depth)545 static DATAFILE *grab_patch(int type, AL_CONST char *filename, DATAFILE_PROPERTY **prop, int depth)
546 {
547 PACKFILE *f;
548 int64_t sz = file_size_ex(filename);
549 char buf[256];
550 int inst, layer, sample, i;
551 int data_size, data_size_pos;
552 int num_instruments, instrument_size, instrument_size_pos;
553 int num_layers, layer_size, layer_size_pos;
554 int num_samples, sample_size;
555 int loop_start, loop_end;
556 int flags;
557 int odd_len;
558
559 if (sz <= 0)
560 return NULL;
561
562 f = pack_fopen(filename, F_READ);
563 if (!f)
564 return NULL;
565
566 if (!opt_8bit) {
567 /* raw copy of the disk file */
568 mem = _AL_MALLOC(sz);
569
570 pack_fread(mem, sz, f);
571 pack_fclose(f);
572
573 if (errno) {
574 _AL_FREE(mem);
575 return NULL;
576 }
577
578 if (opt_verbose) {
579 memcpy(buf, mem+22, 60);
580
581 for (i=0; i<60; i++)
582 if (buf[i] < ' ')
583 break;
584
585 if (i) {
586 buf[i] = 0;
587 printf("%s\n\n", buf);
588 }
589 }
590
591 return datedit_construct(type, mem, sz, prop);
592 }
593
594 /* have to parse the file to adjust the sample format */
595 mem = NULL;
596 mem_size = 0;
597 mem_alloced = 0;
598
599 /* check patch header */
600 pack_fread(buf, 22, f);
601 if (memcmp(buf, "GF1PATCH110\0ID#000002\0", 22)) {
602 pack_fclose(f);
603 return NULL;
604 }
605
606 mem_write_block(buf, 22);
607
608 /* description */
609 pack_fread(buf, 60, f);
610 mem_write_block(buf, 60);
611
612 if (opt_verbose) {
613 for (i=0; i<60; i++)
614 if (buf[i] < ' ')
615 break;
616
617 if (i) {
618 buf[i] = 0;
619 printf("%s\n", buf);
620 }
621 }
622
623 /* how many instruments? */
624 num_instruments = pack_getc(f);
625 mem_write8(num_instruments);
626
627 mem_write_file(f, 6);
628
629 data_size = pack_igetl(f);
630 data_size_pos = mem_size;
631 mem_write32(data_size);
632
633 mem_write_file(f, 36);
634
635 for (inst=0; inst<num_instruments; inst++) {
636 mem_write_file(f, 18);
637
638 instrument_size = pack_igetl(f);
639 instrument_size_pos = mem_size;
640 mem_write32(instrument_size);
641
642 num_layers = pack_getc(f);
643 mem_write8(num_layers);
644
645 mem_write_file(f, 40);
646
647 for (layer=0; layer<num_layers; layer++) {
648 mem_write_file(f, 2);
649
650 layer_size = pack_igetl(f);
651 layer_size_pos = mem_size;
652 mem_write32(layer_size);
653
654 num_samples = pack_getc(f);
655 mem_write8(num_samples);
656
657 mem_write_file(f, 40);
658
659 for (sample=0; sample<num_samples; sample++) {
660 mem_write_file(f, 8);
661
662 sample_size = pack_igetl(f);
663 loop_start = pack_igetl(f);
664 loop_end = pack_igetl(f);
665
666 pack_fread(buf, 35, f);
667
668 flags = pack_getc(f);
669
670 if (flags & 1) {
671 /* adjust 16 bit sample parameters */
672 data_size -= sample_size/2;
673 instrument_size -= sample_size/2;
674 layer_size -= sample_size/2;
675
676 if (sample_size & 1) {
677 data_size--;
678 instrument_size--;
679 layer_size--;
680 odd_len = TRUE;
681 }
682 else
683 odd_len = FALSE;
684
685 mem_modify32(data_size_pos, data_size);
686 mem_modify32(instrument_size_pos, instrument_size);
687 mem_modify32(layer_size_pos, layer_size);
688
689 sample_size /= 2;
690 loop_start /= 2;
691 loop_end /= 2;
692 }
693 else
694 odd_len = FALSE;
695
696 mem_write32(sample_size);
697 mem_write32(loop_start);
698 mem_write32(loop_end);
699 mem_write_block(buf, 35);
700
701 /* change flags to 8 bit */
702 mem_write8((flags & ~1) | 2);
703
704 mem_write_file(f, 40);
705
706 if (flags & 1) {
707 /* reduce 16 bit sample data */
708 if (flags & 2) {
709 for (i=0; i<sample_size; i++)
710 mem_write8(pack_igetw(f) >> 8);
711 }
712 else {
713 for (i=0; i<sample_size; i++)
714 mem_write8((pack_igetw(f) >> 8) ^ 0x80);
715 }
716 if (odd_len)
717 pack_getc(f);
718 }
719 else {
720 /* copy 8 bit waveform */
721 if (flags & 2) {
722 for (i=0; i<sample_size; i++)
723 mem_write8(pack_getc(f));
724 }
725 else {
726 for (i=0; i<sample_size; i++)
727 mem_write8(pack_getc(f) ^ 0x80);
728 }
729 }
730 }
731 }
732 }
733
734 pack_fclose(f);
735
736 if (errno) {
737 _AL_FREE(mem);
738 return NULL;
739 }
740
741 return datedit_construct(type, mem, mem_size, prop);
742 }
743
744
745
746 /* splits a string into component parts */
parse_string(char * buf,char * argv[])747 static int parse_string(char *buf, char *argv[])
748 {
749 int c = 0;
750
751 while ((*buf) && (c<16)) {
752 while ((*buf == ' ') || (*buf == '\t') || (*buf == '='))
753 buf++;
754
755 if (*buf == '#')
756 return c;
757
758 if (*buf)
759 argv[c++] = buf;
760
761 while ((*buf) && (*buf != ' ') && (*buf != '\t') && (*buf != '='))
762 buf++;
763
764 if (*buf) {
765 *buf = 0;
766 buf++;
767 }
768 }
769
770 return c;
771 }
772
773
774
775 /* inserts all the required patches into the datafile */
add_gus_patches(void)776 static void add_gus_patches(void)
777 {
778 char dir[256], file[256], buf[256], filename[256];
779 DATEDIT_GRAB_PARAMETERS params;
780 PACKFILE *f;
781 DATAFILE *d;
782 char *argv[16];
783 int argc;
784 int patchnum;
785 int flag_num;
786 int drum_mode = FALSE;
787 int override_mode = FALSE;
788 int drum_start = 0;
789 int i, j;
790
791 if (opt_configfile) {
792 if (!file_exists(opt_configfile, FA_RDONLY | FA_ARCH, NULL)) {
793 fprintf(stderr, "Error: %s not found\n", opt_configfile);
794 err = 1;
795 return;
796 }
797 strcpy(dir, opt_configfile);
798 *get_filename(dir) = 0;
799 strcpy(file, get_filename(opt_configfile));
800 }
801 else {
802 if (!_digmid_find_patches(dir, sizeof dir, file, sizeof file)) {
803 fprintf(stderr, "\nError: MIDI patch set not found!\n\n");
804 fprintf(stderr, "You should have a directory containing a collection of GUS format .pat\n");
805 fprintf(stderr, "files and a default.cfg index file, or a SoundFont 2 .sf2 sample bank.\n");
806 fprintf(stderr, "Specify your default.cfg or .sf2 file on the pat2dat command line.\n");
807 err = 1;
808 return;
809 }
810 }
811
812 strcpy(buf, dir);
813 strcat(buf, file);
814 fix_filename_case(buf);
815 for (i=0; buf[i]; i++)
816 if (buf[i] == '\\')
817 buf[i] = '/';
818
819 params.datafile = NULL; /* only with absolute filenames */
820 params.filename = buf;
821 params.name = "default_cfg";
822 params.type = DAT_DATA;
823 /* params.x = */
824 /* params.y = */
825 /* params.w = */
826 /* params.h = */
827 /* params.colordepth = */
828 params.relative = FALSE; /* required (see above) */
829
830 printf("Grabbing %s\n", buf);
831 d = datedit_grabnew(datafile, ¶ms);
832 if (!d) {
833 errno = err = 1;
834 return;
835 }
836 else
837 datafile = d;
838
839 if (opt_verbose)
840 printf("\n");
841
842 f = pack_fopen(buf, F_READ);
843 if (!f) {
844 fprintf(stderr, "Error reading %s\n", buf);
845 err = 1;
846 return;
847 }
848
849 while (pack_fgets(buf, 255, f) != 0) {
850 argc = parse_string(buf, argv);
851
852 if (argc > 0) {
853 /* is first word all digits? */
854 flag_num = TRUE;
855 for (i=0; i<(int)strlen(argv[0]); i++) {
856 if ((!uisdigit(argv[0][i])) && (argv[0][i] != '-')) {
857 flag_num = FALSE;
858 break;
859 }
860 }
861
862 if ((flag_num) && (argc >= 2)) {
863 if (stricmp(argv[1], "begin_multipatch") == 0) {
864 /* start the block of percussion instruments */
865 drum_start = atoi(argv[0])-1;
866 drum_mode = TRUE;
867 }
868 else if (stricmp(argv[1], "override_patch") == 0) {
869 /* ignore patch overrides */
870 override_mode = TRUE;
871 }
872 else if (!override_mode) {
873 /* must be a patch number */
874 patchnum = atoi(argv[0]);
875
876 if (!drum_mode)
877 patchnum--;
878
879 if ((patchnum >= 0) && (patchnum < 128) &&
880 (((drum_mode) && (need_drums[patchnum])) ||
881 ((!drum_mode) && (need_patches[patchnum])))) {
882
883 if (drum_mode)
884 patchnum += drum_start;
885
886 /* grab the sample */
887 strcpy(filename, dir);
888 strcat(filename, argv[1]);
889 if ((*get_extension(filename) == 0) && (!strchr(filename, '#')))
890 strcat(filename, ".pat");
891
892 fix_filename_case(argv[1]);
893 fix_filename_case(filename);
894 for (j=0; filename[j]; j++)
895 if (filename[j] == '\\')
896 filename[j] = '/';
897
898 for (j=0; datafile[j].type != DAT_END; j++)
899 if (stricmp(get_datafile_property(datafile+j, DAT_NAME), argv[1]) == 0)
900 break;
901
902 if (datafile[j].type == DAT_END) {
903 params.filename = filename;
904 params.name = argv[1];
905 params.type = DAT_PATCH;
906 printf("Grabbing %s\n", filename);
907 d = datedit_grabnew(datafile, ¶ms);
908 }
909 else
910 d = datafile;
911
912 if (!d) {
913 errno = err = 1;
914 pack_fclose(f);
915 return;
916 }
917 else {
918 datafile = d;
919
920 if (drum_mode)
921 need_drums[patchnum-drum_start] = FALSE;
922 else
923 need_patches[patchnum] = FALSE;
924 }
925 }
926 }
927 }
928 else {
929 /* handle other keywords */
930 if (stricmp(argv[0], "end_multipatch") == 0) {
931 drum_mode = FALSE;
932 override_mode = FALSE;
933 }
934 }
935 }
936 }
937
938 pack_fclose(f);
939 }
940
941
942
943 /* SoundFont chunk format and ID values */
944 typedef struct RIFF_CHUNK
945 {
946 int size;
947 int id;
948 int type;
949 int end;
950 } RIFF_CHUNK;
951
952
953 #define CID(a,b,c,d) (((d)<<24)+((c)<<16)+((b)<<8)+((a)))
954
955
956 #define CID_RIFF CID('R','I','F','F')
957 #define CID_LIST CID('L','I','S','T')
958 #define CID_INFO CID('I','N','F','O')
959 #define CID_sdta CID('s','d','t','a')
960 #define CID_snam CID('s','n','a','m')
961 #define CID_smpl CID('s','m','p','l')
962 #define CID_pdta CID('p','d','t','a')
963 #define CID_phdr CID('p','h','d','r')
964 #define CID_pbag CID('p','b','a','g')
965 #define CID_pmod CID('p','m','o','d')
966 #define CID_pgen CID('p','g','e','n')
967 #define CID_inst CID('i','n','s','t')
968 #define CID_ibag CID('i','b','a','g')
969 #define CID_imod CID('i','m','o','d')
970 #define CID_igen CID('i','g','e','n')
971 #define CID_shdr CID('s','h','d','r')
972 #define CID_ifil CID('i','f','i','l')
973 #define CID_isng CID('i','s','n','g')
974 #define CID_irom CID('i','r','o','m')
975 #define CID_iver CID('i','v','e','r')
976 #define CID_INAM CID('I','N','A','M')
977 #define CID_IPRD CID('I','P','R','D')
978 #define CID_ICOP CID('I','C','O','P')
979 #define CID_sfbk CID('s','f','b','k')
980 #define CID_ICRD CID('I','C','R','D')
981 #define CID_IENG CID('I','E','N','G')
982 #define CID_ICMT CID('I','C','M','T')
983 #define CID_ISFT CID('I','S','F','T')
984
985
986
987 /* SoundFont generator types */
988 #define SFGEN_startAddrsOffset 0
989 #define SFGEN_endAddrsOffset 1
990 #define SFGEN_startloopAddrsOffset 2
991 #define SFGEN_endloopAddrsOffset 3
992 #define SFGEN_startAddrsCoarseOffset 4
993 #define SFGEN_modLfoToPitch 5
994 #define SFGEN_vibLfoToPitch 6
995 #define SFGEN_modEnvToPitch 7
996 #define SFGEN_initialFilterFc 8
997 #define SFGEN_initialFilterQ 9
998 #define SFGEN_modLfoToFilterFc 10
999 #define SFGEN_modEnvToFilterFc 11
1000 #define SFGEN_endAddrsCoarseOffset 12
1001 #define SFGEN_modLfoToVolume 13
1002 #define SFGEN_unused1 14
1003 #define SFGEN_chorusEffectsSend 15
1004 #define SFGEN_reverbEffectsSend 16
1005 #define SFGEN_pan 17
1006 #define SFGEN_unused2 18
1007 #define SFGEN_unused3 19
1008 #define SFGEN_unused4 20
1009 #define SFGEN_delayModLFO 21
1010 #define SFGEN_freqModLFO 22
1011 #define SFGEN_delayVibLFO 23
1012 #define SFGEN_freqVibLFO 24
1013 #define SFGEN_delayModEnv 25
1014 #define SFGEN_attackModEnv 26
1015 #define SFGEN_holdModEnv 27
1016 #define SFGEN_decayModEnv 28
1017 #define SFGEN_sustainModEnv 29
1018 #define SFGEN_releaseModEnv 30
1019 #define SFGEN_keynumToModEnvHold 31
1020 #define SFGEN_keynumToModEnvDecay 32
1021 #define SFGEN_delayVolEnv 33
1022 #define SFGEN_attackVolEnv 34
1023 #define SFGEN_holdVolEnv 35
1024 #define SFGEN_decayVolEnv 36
1025 #define SFGEN_sustainVolEnv 37
1026 #define SFGEN_releaseVolEnv 38
1027 #define SFGEN_keynumToVolEnvHold 39
1028 #define SFGEN_keynumToVolEnvDecay 40
1029 #define SFGEN_instrument 41
1030 #define SFGEN_reserved1 42
1031 #define SFGEN_keyRange 43
1032 #define SFGEN_velRange 44
1033 #define SFGEN_startloopAddrsCoarse 45
1034 #define SFGEN_keynum 46
1035 #define SFGEN_velocity 47
1036 #define SFGEN_initialAttenuation 48
1037 #define SFGEN_reserved2 49
1038 #define SFGEN_endloopAddrsCoarse 50
1039 #define SFGEN_coarseTune 51
1040 #define SFGEN_fineTune 52
1041 #define SFGEN_sampleID 53
1042 #define SFGEN_sampleModes 54
1043 #define SFGEN_reserved3 55
1044 #define SFGEN_scaleTuning 56
1045 #define SFGEN_exclusiveClass 57
1046 #define SFGEN_overridingRootKey 58
1047 #define SFGEN_unused5 59
1048 #define SFGEN_endOper 60
1049
1050
1051
1052 /* SoundFont sample data */
1053 static short *sf_sample_data = NULL;
1054 static int sf_sample_data_size = 0;
1055
1056
1057
1058 /* SoundFont preset headers */
1059 typedef struct sfPresetHeader
1060 {
1061 char achPresetName[20];
1062 unsigned short wPreset;
1063 unsigned short wBank;
1064 unsigned short wPresetBagNdx;
1065 unsigned long dwLibrary;
1066 unsigned long dwGenre;
1067 unsigned long dwMorphology;
1068 } sfPresetHeader;
1069
1070
1071 static sfPresetHeader *sf_presets = NULL;
1072 static int sf_num_presets = 0;
1073
1074
1075
1076 /* SoundFont preset indexes */
1077 typedef struct sfPresetBag
1078 {
1079 unsigned short wGenNdx;
1080 unsigned short wModNdx;
1081 } sfPresetBag;
1082
1083
1084 static sfPresetBag *sf_preset_indexes = NULL;
1085 static int sf_num_preset_indexes = 0;
1086
1087
1088
1089 /* SoundFont preset generators */
1090 typedef struct rangesType
1091 {
1092 unsigned char byLo;
1093 unsigned char byHi;
1094 } rangesType;
1095
1096
1097 typedef union genAmountType
1098 {
1099 rangesType ranges;
1100 short shAmount;
1101 unsigned short wAmount;
1102 } genAmountType;
1103
1104
1105 typedef struct sfGenList
1106 {
1107 unsigned short sfGenOper;
1108 genAmountType genAmount;
1109 } sfGenList;
1110
1111
1112 static sfGenList *sf_preset_generators = NULL;
1113 static int sf_num_preset_generators = 0;
1114
1115
1116
1117 /* SoundFont instrument headers */
1118 typedef struct sfInst
1119 {
1120 char achInstName[20];
1121 unsigned short wInstBagNdx;
1122 } sfInst;
1123
1124
1125 static sfInst *sf_instruments = NULL;
1126 static int sf_num_instruments = 0;
1127
1128
1129
1130 /* SoundFont instrument indexes */
1131 typedef struct sfInstBag
1132 {
1133 unsigned short wInstGenNdx;
1134 unsigned short wInstModNdx;
1135 } sfInstBag;
1136
1137
1138 static sfInstBag *sf_instrument_indexes = NULL;
1139 static int sf_num_instrument_indexes = 0;
1140
1141
1142
1143 /* SoundFont instrument generators */
1144 static sfGenList *sf_instrument_generators = NULL;
1145 static int sf_num_instrument_generators = 0;
1146
1147
1148
1149 /* SoundFont sample headers */
1150 typedef struct sfSample
1151 {
1152 char achSampleName[20];
1153 unsigned long dwStart;
1154 unsigned long dwEnd;
1155 unsigned long dwStartloop;
1156 unsigned long dwEndloop;
1157 unsigned long dwSampleRate;
1158 unsigned char byOriginalKey;
1159 signed char chCorrection;
1160 unsigned short wSampleLink;
1161 unsigned short sfSampleType;
1162 } sfSample;
1163
1164
1165 static sfSample *sf_samples = NULL;
1166 static int sf_num_samples = 0;
1167
1168
1169
1170 /* list of the layers waiting to be dealt with */
1171 typedef struct EMPTY_WHITE_ROOM
1172 {
1173 sfSample *sample;
1174 sfGenList *igen;
1175 sfGenList *pgen;
1176 int igen_count;
1177 int pgen_count;
1178 float volume;
1179 } EMPTY_WHITE_ROOM;
1180
1181 #define MAX_WAITING 64
1182
1183 static EMPTY_WHITE_ROOM waiting_list[MAX_WAITING];
1184
1185 static int waiting_list_count;
1186
1187
1188
1189 /* SoundFont parameters for the current sample */
1190 static int sf_start, sf_end;
1191 static int sf_loop_start, sf_loop_end;
1192 static int sf_key, sf_tune;
1193 static int sf_pan;
1194 static int sf_keyscale;
1195 static int sf_keymin, sf_keymax;
1196 static int sf_sustain_mod_env;
1197 static int sf_mod_env_to_pitch;
1198 static int sf_delay_vol_env;
1199 static int sf_attack_vol_env;
1200 static int sf_hold_vol_env;
1201 static int sf_decay_vol_env;
1202 static int sf_release_vol_env;
1203 static int sf_sustain_level;
1204 static int sf_mode;
1205
1206
1207
1208 /* interprets a SoundFont generator object */
apply_generator(sfGenList * g,int preset)1209 static void apply_generator(sfGenList *g, int preset)
1210 {
1211 switch (g->sfGenOper) {
1212
1213 case SFGEN_startAddrsOffset:
1214 sf_start += g->genAmount.shAmount;
1215 break;
1216
1217 case SFGEN_endAddrsOffset:
1218 sf_end += g->genAmount.shAmount;
1219 break;
1220
1221 case SFGEN_startloopAddrsOffset:
1222 sf_loop_start += g->genAmount.shAmount;
1223 break;
1224
1225 case SFGEN_endloopAddrsOffset:
1226 sf_loop_end += g->genAmount.shAmount;
1227 break;
1228
1229 case SFGEN_startAddrsCoarseOffset:
1230 sf_start += (int)g->genAmount.shAmount * 32768;
1231 break;
1232
1233 case SFGEN_endAddrsCoarseOffset:
1234 sf_end += (int)g->genAmount.shAmount * 32768;
1235 break;
1236
1237 case SFGEN_startloopAddrsCoarse:
1238 sf_loop_start += (int)g->genAmount.shAmount * 32768;
1239 break;
1240
1241 case SFGEN_endloopAddrsCoarse:
1242 sf_loop_end += (int)g->genAmount.shAmount * 32768;
1243 break;
1244
1245 case SFGEN_modEnvToPitch:
1246 if (preset)
1247 sf_mod_env_to_pitch += g->genAmount.shAmount;
1248 else
1249 sf_mod_env_to_pitch = g->genAmount.shAmount;
1250 break;
1251
1252 case SFGEN_sustainModEnv:
1253 if (preset)
1254 sf_sustain_mod_env += g->genAmount.shAmount;
1255 else
1256 sf_sustain_mod_env = g->genAmount.shAmount;
1257 break;
1258
1259 case SFGEN_delayVolEnv:
1260 if (preset)
1261 sf_delay_vol_env += g->genAmount.shAmount;
1262 else
1263 sf_delay_vol_env = g->genAmount.shAmount;
1264 break;
1265
1266 case SFGEN_attackVolEnv:
1267 if (preset)
1268 sf_attack_vol_env += g->genAmount.shAmount;
1269 else
1270 sf_attack_vol_env = g->genAmount.shAmount;
1271 break;
1272
1273 case SFGEN_holdVolEnv:
1274 if (preset)
1275 sf_hold_vol_env += g->genAmount.shAmount;
1276 else
1277 sf_hold_vol_env = g->genAmount.shAmount;
1278 break;
1279
1280 case SFGEN_decayVolEnv:
1281 if (preset)
1282 sf_decay_vol_env += g->genAmount.shAmount;
1283 else
1284 sf_decay_vol_env = g->genAmount.shAmount;
1285 break;
1286
1287 case SFGEN_sustainVolEnv:
1288 if (preset)
1289 sf_sustain_level += g->genAmount.shAmount;
1290 else
1291 sf_sustain_level = g->genAmount.shAmount;
1292 break;
1293
1294 case SFGEN_releaseVolEnv:
1295 if (preset)
1296 sf_release_vol_env += g->genAmount.shAmount;
1297 else
1298 sf_release_vol_env = g->genAmount.shAmount;
1299 break;
1300
1301 case SFGEN_pan:
1302 if (preset)
1303 sf_pan += g->genAmount.shAmount;
1304 else
1305 sf_pan = g->genAmount.shAmount;
1306 break;
1307
1308 case SFGEN_keyRange:
1309 sf_keymin = g->genAmount.ranges.byLo;
1310 sf_keymax = g->genAmount.ranges.byHi;
1311 break;
1312
1313 case SFGEN_coarseTune:
1314 sf_tune += (int)g->genAmount.shAmount * 100;
1315 break;
1316
1317 case SFGEN_fineTune:
1318 sf_tune += g->genAmount.shAmount;
1319 break;
1320
1321 case SFGEN_sampleModes:
1322 sf_mode = g->genAmount.wAmount;
1323 break;
1324
1325 case SFGEN_scaleTuning:
1326 if (preset)
1327 sf_keyscale += g->genAmount.shAmount;
1328 else
1329 sf_keyscale = g->genAmount.shAmount;
1330 break;
1331
1332 case SFGEN_overridingRootKey:
1333 sf_key = g->genAmount.shAmount;
1334 break;
1335 }
1336 }
1337
1338
1339
1340 /* converts AWE32 (MIDI) pitches to GUS (frequency) format */
key2freq(int note,int cents)1341 static int key2freq(int note, int cents)
1342 {
1343 return pow(2.0, (float)(note*100+cents)/1200.0) * 8175.800781;
1344 }
1345
1346
1347
1348 /* converts the strange AWE32 timecent values to milliseconds */
timecent2msec(int t)1349 static int timecent2msec(int t)
1350 {
1351 return pow(2.0, (float)t/1200.0) * 1000.0;
1352 }
1353
1354
1355
1356 /* converts milliseconds to the even stranger floating point GUS format */
msec2gus(int t,int r)1357 static int msec2gus(int t, int r)
1358 {
1359 static int vexp[4] = { 1, 8, 64, 512 };
1360
1361 int e, m;
1362
1363 t = t * 32 / r;
1364
1365 if (t <= 0)
1366 return 0x3F;
1367
1368 for (e=3; e>=0; e--) {
1369 m = (vexp[e] * 16 + t/2) / t;
1370
1371 if ((m > 0) && (m < 64))
1372 return ((e << 6) | m);
1373 }
1374
1375 return 0xC1;
1376 }
1377
1378
1379
1380 /* copies data from the waiting list into a GUS .pat struct */
grab_soundfont_sample(char * name)1381 static void grab_soundfont_sample(char *name)
1382 {
1383 static char msg[] = "Converted by Allegro pat2dat v" ALLEGRO_VERSION_STR ", " ALLEGRO_PLATFORM_STR;
1384 sfSample *sample;
1385 sfGenList *igen;
1386 sfGenList *pgen;
1387 float vol, total_vol;
1388 int igen_count;
1389 int pgen_count;
1390 int length;
1391 int min_freq, max_freq;
1392 int root_freq;
1393 int decay;
1394 int sustain;
1395 int release;
1396 int flags;
1397 int i, n;
1398
1399 mem = NULL;
1400 mem_size = 0;
1401 mem_alloced = 0;
1402
1403 mem_write_block("GF1PATCH110\0ID#000002\0", 22);
1404
1405 mem_write_block(msg, sizeof(msg)); /* copyright message */
1406 for (i=0; i<60-(int)sizeof(msg); i++)
1407 mem_write8(0);
1408
1409 mem_write8(1); /* number of instruments */
1410 mem_write8(14); /* number of voices */
1411 mem_write8(0); /* number of channels */
1412 mem_write16(waiting_list_count); /* number of waveforms */
1413 mem_write16(127); /* master volume */
1414 mem_write32(0); /* data size (wrong!) */
1415
1416 for (i=0; i<36; i++) /* reserved */
1417 mem_write8(0);
1418
1419 mem_write16(0); /* instrument number */
1420
1421 for (i=0; name[i]; i++) /* instrument name */
1422 mem_write8(name[i]);
1423
1424 while (i < 16) { /* pad instrument name */
1425 mem_write8(0);
1426 i++;
1427 }
1428
1429 mem_write32(0); /* instrument size (wrong!) */
1430 mem_write8(1); /* number of layers */
1431
1432 for (i=0; i<40; i++) /* reserved */
1433 mem_write8(0);
1434
1435 mem_write8(0); /* layer duplicate */
1436 mem_write8(0); /* layer number */
1437 mem_write32(0); /* layer size (wrong!) */
1438 mem_write8(waiting_list_count); /* number of samples */
1439
1440 for (i=0; i<40; i++) /* reserved */
1441 mem_write8(0);
1442
1443 /* bodge alert!!! I don't know how to make the volume parameters come
1444 * out right. If I ignore them, some things are very wrong (eg. with
1445 * the Emu 2MB bank the pads have overloud 'tinkle' layers, and the
1446 * square lead is way too loud). But if I process the attenuation
1447 * parameter the way I think it should be done, other things go wrong
1448 * (the church organ and honkytonk piano come out very quiet). So I
1449 * look at the volume setting and then normalise the results, to get
1450 * the differential between each layer but still keep a uniform overall
1451 * volume for the patch. Totally incorrect, but it usually seems to do
1452 * the right thing...
1453 */
1454
1455 total_vol = 0;
1456
1457 for (n=0; n<waiting_list_count; n++) {
1458 int v = 0;
1459 int keymin = 0;
1460 int keymax = 127;
1461
1462 /* look for volume and keyrange generators */
1463 for (i=0; i<waiting_list[n].igen_count; i++) {
1464 if (waiting_list[n].igen[i].sfGenOper == SFGEN_initialAttenuation) {
1465 v = waiting_list[n].igen[i].genAmount.shAmount;
1466 }
1467 else if (waiting_list[n].igen[i].sfGenOper == SFGEN_keyRange) {
1468 keymin = waiting_list[n].igen[i].genAmount.ranges.byLo;
1469 keymax = waiting_list[n].igen[i].genAmount.ranges.byHi;
1470 }
1471 }
1472
1473 for (i=0; i<waiting_list[n].pgen_count; i++) {
1474 if (waiting_list[n].pgen[i].sfGenOper == SFGEN_initialAttenuation) {
1475 v += waiting_list[n].pgen[i].genAmount.shAmount;
1476 }
1477 else if (waiting_list[n].pgen[i].sfGenOper == SFGEN_keyRange) {
1478 keymin = waiting_list[n].pgen[i].genAmount.ranges.byLo;
1479 keymax = waiting_list[n].pgen[i].genAmount.ranges.byHi;
1480 }
1481 }
1482
1483 /* convert centibels to scaling factor (I _think_ this is right :-) */
1484 vol = 1.0;
1485 while (v-- > 0)
1486 vol /= pow(10, 0.005);
1487
1488 waiting_list[n].volume = vol;
1489
1490 if ((keymin <= 60) && (keymax >= 60))
1491 total_vol += vol;
1492 }
1493
1494 /* normalise the layer volumes so they sum to unity */
1495 if (total_vol > 0) {
1496 for (n=0; n<waiting_list_count; n++)
1497 waiting_list[n].volume = CLAMP(0.2, waiting_list[n].volume/total_vol, 1.0);
1498 }
1499
1500 /* for each sample... */
1501 for (n=0; n<waiting_list_count; n++) {
1502 sample = waiting_list[n].sample;
1503 igen = waiting_list[n].igen;
1504 pgen = waiting_list[n].pgen;
1505 igen_count = waiting_list[n].igen_count;
1506 pgen_count = waiting_list[n].pgen_count;
1507 vol = waiting_list[n].volume;
1508
1509 /* set default generator values */
1510 sf_start = sample->dwStart;
1511 sf_end = sample->dwEnd;
1512 sf_loop_start = sample->dwStartloop;
1513 sf_loop_end = sample->dwEndloop;
1514 sf_key = sample->byOriginalKey;
1515 sf_tune = sample->chCorrection;
1516 sf_sustain_mod_env = 0;
1517 sf_mod_env_to_pitch = 0;
1518 sf_delay_vol_env = -12000;
1519 sf_attack_vol_env = -12000;
1520 sf_hold_vol_env = -12000;
1521 sf_decay_vol_env = -12000;
1522 sf_release_vol_env = -12000;
1523 sf_sustain_level = 0;
1524 sf_pan = 0;
1525 sf_keyscale = 100;
1526 sf_keymin = 0;
1527 sf_keymax = 127;
1528 sf_mode = 0;
1529
1530 /* process the lists of generator data */
1531 for (i=0; i<igen_count; i++)
1532 apply_generator(&igen[i], FALSE);
1533
1534 for (i=0; i<pgen_count; i++)
1535 apply_generator(&pgen[i], TRUE);
1536
1537 /* convert SoundFont values into some more useful formats */
1538 length = sf_end - sf_start;
1539
1540 sf_loop_start = CLAMP(0, sf_loop_start-sf_start, sf_end);
1541 sf_loop_end = CLAMP(0, sf_loop_end-sf_start, sf_end);
1542
1543 sf_pan = CLAMP(0, sf_pan*16/1000+7, 15);
1544 sf_keyscale = CLAMP(0, sf_keyscale*1024/100, 2048);
1545
1546 sf_tune += sf_mod_env_to_pitch * CLAMP(0, 1000-sf_sustain_mod_env, 1000) / 1000;
1547
1548 min_freq = key2freq(sf_keymin, 0);
1549 max_freq = key2freq(sf_keymax+1, 0) - 1;
1550 root_freq = key2freq(sf_key, -sf_tune);
1551
1552 sustain = CLAMP(0, (1000-sf_sustain_level)*255/1000, 255);
1553
1554 decay = timecent2msec(sf_delay_vol_env) +
1555 timecent2msec(sf_attack_vol_env) +
1556 timecent2msec(sf_hold_vol_env) +
1557 timecent2msec(sf_decay_vol_env);
1558
1559 release = timecent2msec(sf_release_vol_env);
1560
1561 /* The output from this code is almost certainly not a 'correct'
1562 * .pat file. There are a lot of things I don't know about the
1563 * format, which have been filled in by guesses or values copied
1564 * from the Gravis files. And I have no idea what I'm supposed to
1565 * put in all the size fields, which are currently set to zero :-)
1566 *
1567 * But, the results are good enough for DIGMID to understand, and
1568 * the CONVERT program also seems quite happy to accept them, so
1569 * it is at least mostly correct...
1570 */
1571
1572 mem_write8('s'); /* sample name */
1573 mem_write8('a');
1574 mem_write8('m');
1575 mem_write8('p');
1576 mem_write8('0'+(n+1)/10);
1577 mem_write8('0'+(n+1)%10);
1578 mem_write8(0);
1579
1580 mem_write8(0); /* fractions */
1581
1582 if (opt_8bit) {
1583 mem_write32(length); /* waveform size */
1584 mem_write32(sf_loop_start); /* loop start */
1585 mem_write32(sf_loop_end); /* loop end */
1586 }
1587 else {
1588 mem_write32(length*2); /* waveform size */
1589 mem_write32(sf_loop_start*2); /* loop start */
1590 mem_write32(sf_loop_end*2); /* loop end */
1591 }
1592
1593 mem_write16(sample->dwSampleRate); /* sample freq */
1594
1595 mem_write32(min_freq); /* low freq */
1596 mem_write32(max_freq); /* high freq */
1597 mem_write32(root_freq); /* root frequency */
1598
1599 mem_write16(512); /* finetune */
1600 mem_write8(sf_pan); /* balance */
1601
1602 mem_write8(0x3F); /* envelope rates */
1603 mem_write8(0x3F);
1604 mem_write8(msec2gus(decay, 256-sustain));
1605 mem_write8(0x3F);
1606 mem_write8(msec2gus(release, 256));
1607 mem_write8(0x3F);
1608
1609 mem_write8(255); /* envelope offsets */
1610 mem_write8(255);
1611 mem_write8(sustain);
1612 mem_write8(255);
1613 mem_write8(0);
1614 mem_write8(0);
1615
1616 mem_write8(0x3C); /* tremolo sweep */
1617 mem_write8(0x80); /* tremolo rate */
1618 mem_write8(0); /* tremolo depth */
1619
1620 mem_write8(0x3C); /* vibrato sweep */
1621 mem_write8(0x80); /* vibrato rate */
1622 mem_write8(0); /* vibrato depth */
1623
1624 flags = (32 | 64); /* enable sustain and envelope */
1625
1626 if (opt_8bit)
1627 flags |= 2; /* signed waveform */
1628 else
1629 flags |= 1; /* 16-bit waveform */
1630
1631 if (sf_mode & 1)
1632 flags |= 4; /* looped sample */
1633
1634 mem_write8(flags); /* write sample mode */
1635
1636 mem_write16(60); /* scale frequency */
1637 mem_write16(sf_keyscale); /* scale factor */
1638
1639 for (i=0; i<36; i++) /* reserved */
1640 mem_write8(0);
1641
1642 if (opt_8bit) { /* sample waveform */
1643 for (i=0; i<length; i++)
1644 mem_write8((int)((sf_sample_data[sample->dwStart+i] >> 8) * vol) ^ 0x80);
1645 }
1646 else {
1647 for (i=0; i<length; i++)
1648 mem_write16(sf_sample_data[sample->dwStart+i] * vol);
1649 }
1650 }
1651
1652 datafile = datedit_insert(datafile, NULL, name, DAT_PATCH, mem, mem_size);
1653 }
1654
1655
1656
1657 /* converts loaded SoundFont data */
grab_soundfont(int num,int drum,char * name)1658 static int grab_soundfont(int num, int drum, char *name)
1659 {
1660 sfPresetHeader *pheader;
1661 sfPresetBag *pindex;
1662 sfGenList *pgen;
1663 sfInst *iheader;
1664 sfInstBag *iindex;
1665 sfGenList *igen;
1666 sfSample *sample;
1667 int pindex_count;
1668 int pgen_count;
1669 int iindex_count;
1670 int igen_count;
1671 int pnum, inum, lnum;
1672 int wanted_patch, wanted_bank;
1673 int keymin, keymax;
1674 int waiting_room_full;
1675 int i;
1676 char *s;
1677
1678 if (drum) {
1679 wanted_patch = opt_drum_bank;
1680 wanted_bank = 128;
1681 keymin = num;
1682 keymax = num;
1683 }
1684 else {
1685 wanted_patch = num;
1686 wanted_bank = opt_bank;
1687 keymin = 0;
1688 keymax = 127;
1689 }
1690
1691 /* search for the desired preset */
1692 for (pnum=0; pnum<sf_num_presets; pnum++) {
1693 pheader = &sf_presets[pnum];
1694
1695 if ((pheader->wPreset == wanted_patch) && (pheader->wBank == wanted_bank)) {
1696 /* find what substructures it uses */
1697 pindex = &sf_preset_indexes[pheader->wPresetBagNdx];
1698 pindex_count = pheader[1].wPresetBagNdx - pheader[0].wPresetBagNdx;
1699
1700 if (pindex_count < 1)
1701 return FALSE;
1702
1703 /* prettify the preset name */
1704 s = pheader->achPresetName;
1705
1706 i = strlen(s)-1;
1707 while ((i >= 0) && (uisspace(s[i]))) {
1708 s[i] = 0;
1709 i--;
1710 }
1711
1712 printf("Grabbing %s -> %s\n", s, name);
1713
1714 waiting_list_count = 0;
1715 waiting_room_full = FALSE;
1716
1717 /* for each layer in this preset */
1718 for (inum=0; inum<pindex_count; inum++) {
1719 pgen = &sf_preset_generators[pindex[inum].wGenNdx];
1720 pgen_count = pindex[inum+1].wGenNdx - pindex[inum].wGenNdx;
1721
1722 /* find what instrument we should use */
1723 if ((pgen_count > 0) &&
1724 (pgen[pgen_count-1].sfGenOper == SFGEN_instrument)) {
1725
1726 if (pgen[0].sfGenOper == SFGEN_keyRange)
1727 if ((pgen[0].genAmount.ranges.byHi < keymin) ||
1728 (pgen[0].genAmount.ranges.byLo > keymax))
1729 continue;
1730
1731 iheader = &sf_instruments[pgen[pgen_count-1].genAmount.wAmount];
1732
1733 iindex = &sf_instrument_indexes[iheader->wInstBagNdx];
1734 iindex_count = iheader[1].wInstBagNdx - iheader[0].wInstBagNdx;
1735
1736 /* for each layer in this instrument */
1737 for (lnum=0; lnum<iindex_count; lnum++) {
1738 igen = &sf_instrument_generators[iindex[lnum].wInstGenNdx];
1739 igen_count = iindex[lnum+1].wInstGenNdx - iindex[lnum].wInstGenNdx;
1740
1741 /* find what sample we should use */
1742 if ((igen_count > 0) &&
1743 (igen[igen_count-1].sfGenOper == SFGEN_sampleID)) {
1744
1745 if (igen[0].sfGenOper == SFGEN_keyRange)
1746 if ((igen[0].genAmount.ranges.byHi < keymin) ||
1747 (igen[0].genAmount.ranges.byLo > keymax))
1748 continue;
1749
1750 sample = &sf_samples[igen[igen_count-1].genAmount.wAmount];
1751
1752 /* don't bother with left channel or linked samples */
1753 if (sample->sfSampleType & 12)
1754 continue;
1755
1756 /* prettify the sample name */
1757 s = sample->achSampleName;
1758
1759 i = strlen(s)-1;
1760 while ((i >= 0) && (uisspace(s[i]))) {
1761 s[i] = 0;
1762 i--;
1763 }
1764
1765 if (sample->sfSampleType & 0x8000) {
1766 printf("Error: this SoundFont uses the AWE32 ROM data in sample %s\n", s);
1767 if (opt_veryverbose)
1768 printf("\n");
1769 return FALSE;
1770 }
1771
1772 /* add this sample to the waiting list */
1773 if (waiting_list_count < MAX_WAITING) {
1774 if (opt_veryverbose)
1775 printf(" - sample %s\n", s);
1776
1777 waiting_list[waiting_list_count].sample = sample;
1778 waiting_list[waiting_list_count].igen = igen;
1779 waiting_list[waiting_list_count].pgen = pgen;
1780 waiting_list[waiting_list_count].igen_count = igen_count;
1781 waiting_list[waiting_list_count].pgen_count = pgen_count;
1782 waiting_list[waiting_list_count].volume = 1.0;
1783 waiting_list_count++;
1784 }
1785 else
1786 waiting_room_full = TRUE;
1787 }
1788 }
1789 }
1790 }
1791
1792 if (waiting_room_full)
1793 printf("Warning: too many layers in this instrument!\n");
1794
1795 if (waiting_list_count > 0)
1796 grab_soundfont_sample(name);
1797 else
1798 printf("Strange... no valid layers found!\n");
1799
1800 if (opt_veryverbose)
1801 printf("\n");
1802
1803 return (waiting_list_count > 0);
1804 }
1805 }
1806
1807 return FALSE;
1808 }
1809
1810
1811
1812 /* reads a byte from the input file */
get8(FILE * f)1813 static int get8(FILE *f)
1814 {
1815 return getc(f);
1816 }
1817
1818
1819
1820 /* reads a word from the input file (little endian) */
get16(FILE * f)1821 static int get16(FILE *f)
1822 {
1823 int b1, b2;
1824
1825 b1 = get8(f);
1826 b2 = get8(f);
1827
1828 return ((b2 << 8) | b1);
1829 }
1830
1831
1832
1833 /* reads a long from the input file (little endian) */
get32(FILE * f)1834 static int get32(FILE *f)
1835 {
1836 int b1, b2, b3, b4;
1837
1838 b1 = get8(f);
1839 b2 = get8(f);
1840 b3 = get8(f);
1841 b4 = get8(f);
1842
1843 return ((b4 << 24) | (b3 << 16) | (b2 << 8) | b1);
1844 }
1845
1846
1847
1848 /* calculates the file offset for the end of a chunk */
calc_end(RIFF_CHUNK * chunk,FILE * f)1849 static void calc_end(RIFF_CHUNK *chunk, FILE *f)
1850 {
1851 chunk->end = ftell(f) + chunk->size + (chunk->size & 1);
1852 }
1853
1854
1855
1856 /* reads and displays a SoundFont text/copyright message */
print_sf_string(FILE * f,char * title)1857 static void print_sf_string(FILE *f, char *title)
1858 {
1859 char buf[256];
1860 char ch;
1861 int i = 0;
1862
1863 do {
1864 ch = get8(f);
1865 buf[i++] = ch;
1866 } while ((ch) && (i < 256));
1867
1868 if (i & 1)
1869 get8(f);
1870
1871 if (opt_verbose)
1872 printf("%-12s%s\n", title, buf);
1873 }
1874
1875
1876
1877 /* error handling macro */
1878 #define BAD_SF() \
1879 { \
1880 fprintf(stderr, "Error: bad SoundFont structure\n"); \
1881 err = 1; \
1882 goto getout; \
1883 }
1884
1885
1886
1887 /* inserts all the required patches into the datafile */
add_soundfont_patches(void)1888 static void add_soundfont_patches(void)
1889 {
1890 RIFF_CHUNK file, chunk, subchunk;
1891 DATEDIT_GRAB_PARAMETERS params;
1892 DATAFILE *d;
1893 FILE *f;
1894 time_t now;
1895 char buf[256] = "XXXXXX";
1896 char tm[80];
1897 int i;
1898
1899 #ifdef ALLEGRO_HAVE_MKSTEMP
1900
1901 int tmp_fd;
1902
1903 tmp_fd = mkstemp(buf);
1904 close(tmp_fd);
1905
1906 #else
1907
1908 tmpnam(buf);
1909
1910 #endif
1911
1912 printf("Generating index file\n");
1913
1914 f = fopen(buf, F_WRITE);
1915 if (!f) {
1916 fprintf(stderr, "Error writing temporary file\n");
1917 err = 1;
1918 return;
1919 }
1920
1921 time(&now);
1922 strcpy(tm, asctime(localtime(&now)));
1923 for (i=0; tm[i]; i++)
1924 if ((tm[i] == '\r') || (tm[i] == '\n'))
1925 tm[i] = 0;
1926
1927 fprintf(f, "# Patch index for the Allegro DIGMID driver\n");
1928 fprintf(f, "# Produced by pat2dat v" ALLEGRO_VERSION_STR ", " ALLEGRO_PLATFORM_STR "\n");
1929 fprintf(f, "# Date: %s\n\n", tm);
1930
1931 fprintf(f, "0 %s\n", short_patch_names[0]);
1932
1933 for (i=0; i<128; i++)
1934 fprintf(f, "%d %s\n", i+1, short_patch_names[i]);
1935
1936 fprintf(f, "\n129-256 begin_multipatch default blank\n");
1937
1938 for (i=35; i<82; i++)
1939 fprintf(f, "\t%d %s\n", i, short_drum_names[i-35]);
1940
1941 fprintf(f, "end_multipatch\n");
1942
1943 fclose(f);
1944
1945 params.datafile = NULL; /* only with absolute filenames */
1946 params.filename = buf;
1947 params.name = "default_cfg";
1948 params.type = DAT_DATA;
1949 /* params.x = */
1950 /* params.y = */
1951 /* params.w = */
1952 /* params.h = */
1953 /* params.colordepth = */
1954 params.relative = FALSE; /* required (see above) */
1955
1956 d = datedit_grabnew(datafile, ¶ms);
1957
1958 delete_file(buf);
1959
1960 if (!d) {
1961 errno = err = 1;
1962 return;
1963 }
1964 else
1965 datafile = d;
1966
1967 if (opt_verbose)
1968 printf("\nReading %s\n\n", opt_soundfont);
1969 else
1970 printf("Reading %s\n", opt_soundfont);
1971
1972 f = fopen(opt_soundfont, "rb");
1973 if (!f) {
1974 fprintf(stderr, "Error opening file\n");
1975 err = 1;
1976 return;
1977 }
1978
1979 file.id = get32(f);
1980 if (file.id != CID_RIFF) {
1981 fprintf(stderr, "Error: bad SoundFont header\n");
1982 err = 1;
1983 goto getout;
1984 }
1985
1986 file.size = get32(f);
1987 calc_end(&file, f);
1988 file.type = get32(f);
1989 if (file.type != CID_sfbk) {
1990 fprintf(stderr, "Error: bad SoundFont header\n");
1991 err = 1;
1992 goto getout;
1993 }
1994
1995 while (ftell(f) < file.end) {
1996 chunk.id = get32(f);
1997 chunk.size = get32(f);
1998 calc_end(&chunk, f);
1999
2000 switch (chunk.id) {
2001
2002 case CID_LIST:
2003 /* a list of other chunks */
2004 chunk.type = get32(f);
2005
2006 while (ftell(f) < chunk.end) {
2007 subchunk.id = get32(f);
2008 subchunk.size = get32(f);
2009 calc_end(&subchunk, f);
2010
2011 switch (chunk.type) {
2012
2013 case CID_INFO:
2014 /* information block */
2015 switch (subchunk.id) {
2016
2017 case CID_ifil:
2018 if (get16(f) < 2) {
2019 fprintf(stderr, "Error: this is a SoundFont 1.x file, and I only understand version 2 (.sf2)\n");
2020 err = 1;
2021 goto getout;
2022 }
2023 get16(f);
2024 break;
2025
2026 case CID_INAM:
2027 print_sf_string(f, "Bank name:");
2028 break;
2029
2030 case CID_irom:
2031 print_sf_string(f, "ROM name:");
2032 break;
2033
2034 case CID_ICRD:
2035 print_sf_string(f, "Date:");
2036 break;
2037
2038 case CID_IENG:
2039 print_sf_string(f, "Made by:");
2040 break;
2041
2042 case CID_IPRD:
2043 print_sf_string(f, "Target:");
2044 break;
2045
2046 case CID_ICOP:
2047 print_sf_string(f, "Copyright:");
2048 break;
2049
2050 case CID_ISFT:
2051 print_sf_string(f, "Tools:");
2052 break;
2053 }
2054
2055 /* skip unknown chunks and extra data */
2056 fseek(f, subchunk.end, SEEK_SET);
2057 break;
2058
2059 case CID_pdta:
2060 /* preset, instrument and sample header data */
2061 switch (subchunk.id) {
2062
2063 case CID_phdr:
2064 /* preset headers */
2065 sf_num_presets = subchunk.size/38;
2066
2067 if ((sf_num_presets*38 != subchunk.size) ||
2068 (sf_num_presets < 2) || (sf_presets))
2069 BAD_SF();
2070
2071 sf_presets = malloc(sizeof(sfPresetHeader) * sf_num_presets);
2072
2073 for (i=0; i<sf_num_presets; i++) {
2074 fread(sf_presets[i].achPresetName, 20, 1, f);
2075 sf_presets[i].wPreset = get16(f);
2076 sf_presets[i].wBank = get16(f);
2077 sf_presets[i].wPresetBagNdx = get16(f);
2078 sf_presets[i].dwLibrary = get32(f);
2079 sf_presets[i].dwGenre = get32(f);
2080 sf_presets[i].dwMorphology = get32(f);
2081 }
2082 break;
2083
2084 case CID_pbag:
2085 /* preset index list */
2086 sf_num_preset_indexes = subchunk.size/4;
2087
2088 if ((sf_num_preset_indexes*4 != subchunk.size) ||
2089 (sf_preset_indexes))
2090 BAD_SF();
2091
2092 sf_preset_indexes = malloc(sizeof(sfPresetBag) * sf_num_preset_indexes);
2093
2094 for (i=0; i<sf_num_preset_indexes; i++) {
2095 sf_preset_indexes[i].wGenNdx = get16(f);
2096 sf_preset_indexes[i].wModNdx = get16(f);
2097 }
2098 break;
2099
2100 case CID_pgen:
2101 /* preset generator list */
2102 sf_num_preset_generators = subchunk.size/4;
2103
2104 if ((sf_num_preset_generators*4 != subchunk.size) ||
2105 (sf_preset_generators))
2106 BAD_SF();
2107
2108 sf_preset_generators = malloc(sizeof(sfGenList) * sf_num_preset_generators);
2109
2110 for (i=0; i<sf_num_preset_generators; i++) {
2111 sf_preset_generators[i].sfGenOper = get16(f);
2112 sf_preset_generators[i].genAmount.wAmount = get16(f);
2113 }
2114 break;
2115
2116 case CID_inst:
2117 /* instrument names and indices */
2118 sf_num_instruments = subchunk.size/22;
2119
2120 if ((sf_num_instruments*22 != subchunk.size) ||
2121 (sf_num_instruments < 2) || (sf_instruments))
2122 BAD_SF();
2123
2124 sf_instruments = malloc(sizeof(sfInst) * sf_num_instruments);
2125
2126 for (i=0; i<sf_num_instruments; i++) {
2127 fread(sf_instruments[i].achInstName, 20, 1, f);
2128 sf_instruments[i].wInstBagNdx = get16(f);
2129 }
2130 break;
2131
2132 case CID_ibag:
2133 /* instrument index list */
2134 sf_num_instrument_indexes = subchunk.size/4;
2135
2136 if ((sf_num_instrument_indexes*4 != subchunk.size) ||
2137 (sf_instrument_indexes))
2138 BAD_SF();
2139
2140 sf_instrument_indexes = malloc(sizeof(sfInstBag) * sf_num_instrument_indexes);
2141
2142 for (i=0; i<sf_num_instrument_indexes; i++) {
2143 sf_instrument_indexes[i].wInstGenNdx = get16(f);
2144 sf_instrument_indexes[i].wInstModNdx = get16(f);
2145 }
2146 break;
2147
2148 case CID_igen:
2149 /* instrument generator list */
2150 sf_num_instrument_generators = subchunk.size/4;
2151
2152 if ((sf_num_instrument_generators*4 != subchunk.size) ||
2153 (sf_instrument_generators))
2154 BAD_SF();
2155
2156 sf_instrument_generators = malloc(sizeof(sfGenList) * sf_num_instrument_generators);
2157
2158 for (i=0; i<sf_num_instrument_generators; i++) {
2159 sf_instrument_generators[i].sfGenOper = get16(f);
2160 sf_instrument_generators[i].genAmount.wAmount = get16(f);
2161 }
2162 break;
2163
2164 case CID_shdr:
2165 /* sample headers */
2166 sf_num_samples = subchunk.size/46;
2167
2168 if ((sf_num_samples*46 != subchunk.size) ||
2169 (sf_num_samples < 2) || (sf_samples))
2170 BAD_SF();
2171
2172 sf_samples = malloc(sizeof(sfSample) * sf_num_samples);
2173
2174 for (i=0; i<sf_num_samples; i++) {
2175 fread(sf_samples[i].achSampleName, 20, 1, f);
2176 sf_samples[i].dwStart = get32(f);
2177 sf_samples[i].dwEnd = get32(f);
2178 sf_samples[i].dwStartloop = get32(f);
2179 sf_samples[i].dwEndloop = get32(f);
2180 sf_samples[i].dwSampleRate = get32(f);
2181 sf_samples[i].byOriginalKey = get8(f);
2182 sf_samples[i].chCorrection = get8(f);
2183 sf_samples[i].wSampleLink = get16(f);
2184 sf_samples[i].sfSampleType = get16(f);
2185 }
2186 break;
2187 }
2188
2189 /* skip unknown chunks and extra data */
2190 fseek(f, subchunk.end, SEEK_SET);
2191 break;
2192
2193 case CID_sdta:
2194 /* sample data block */
2195 switch (subchunk.id) {
2196
2197 case CID_smpl:
2198 /* sample waveform (all in one) */
2199 if (sf_sample_data)
2200 BAD_SF();
2201
2202 sf_sample_data_size = subchunk.size / 2;
2203 sf_sample_data = malloc(sizeof(short) * sf_sample_data_size);
2204
2205 for (i=0; i<sf_sample_data_size; i++)
2206 sf_sample_data[i] = get16(f);
2207
2208 break;
2209 }
2210
2211 /* skip unknown chunks and extra data */
2212 fseek(f, subchunk.end, SEEK_SET);
2213 break;
2214
2215 default:
2216 /* unrecognised chunk */
2217 fseek(f, chunk.end, SEEK_SET);
2218 break;
2219 }
2220 }
2221 break;
2222
2223 default:
2224 /* not a list so we're not interested */
2225 fseek(f, chunk.end, SEEK_SET);
2226 break;
2227 }
2228
2229 if (feof(f))
2230 BAD_SF();
2231 }
2232
2233 getout:
2234
2235 if (f)
2236 fclose(f);
2237
2238 /* convert SoundFont to .pat format, and add it to the output datafile */
2239 if (!err) {
2240 if ((!sf_sample_data) || (!sf_presets) ||
2241 (!sf_preset_indexes) || (!sf_preset_generators) ||
2242 (!sf_instruments) || (!sf_instrument_indexes) ||
2243 (!sf_instrument_generators) || (!sf_samples))
2244 BAD_SF();
2245
2246 if (opt_verbose)
2247 printf("\n");
2248
2249 for (i=0; (i<128) && (!err); i++) {
2250 if (need_patches[i]) {
2251 if (grab_soundfont(i, FALSE, short_patch_names[i]))
2252 need_patches[i] = FALSE;
2253 }
2254 }
2255
2256 for (i=35; (i<82) && (!err); i++) {
2257 if (need_drums[i]) {
2258 if (grab_soundfont(i, TRUE, short_drum_names[i-35]))
2259 need_drums[i] = FALSE;
2260 }
2261 }
2262 }
2263
2264 /* oh, how polite I am... */
2265 if (sf_sample_data) {
2266 free(sf_sample_data);
2267 sf_sample_data = NULL;
2268 }
2269
2270 if (sf_presets) {
2271 free(sf_presets);
2272 sf_presets = NULL;
2273 }
2274
2275 if (sf_preset_indexes) {
2276 free(sf_preset_indexes);
2277 sf_preset_indexes = NULL;
2278 }
2279
2280 if (sf_preset_generators) {
2281 free(sf_preset_generators);
2282 sf_preset_generators = NULL;
2283 }
2284
2285 if (sf_instruments) {
2286 free(sf_instruments);
2287 sf_instruments = NULL;
2288 }
2289
2290 if (sf_instrument_indexes) {
2291 free(sf_instrument_indexes);
2292 sf_instrument_indexes = NULL;
2293 }
2294
2295 if (sf_instrument_generators) {
2296 free(sf_instrument_generators);
2297 sf_instrument_generators = NULL;
2298 }
2299
2300 if (sf_samples) {
2301 free(sf_samples);
2302 sf_samples = NULL;
2303 }
2304 }
2305
2306
2307
main(int argc,char * argv[])2308 int main(int argc, char *argv[])
2309 {
2310 int c;
2311
2312 if (install_allegro(SYSTEM_NONE, &errno, atexit) != 0)
2313 return 1;
2314 datedit_init();
2315
2316 for (c=0; c<128; c++)
2317 need_patches[c] = need_drums[c] = FALSE;
2318
2319 for (c=0; datedit_grabber_info[c]->type != DAT_END; c++) {
2320 if (datedit_grabber_info[c]->type == DAT_PATCH) {
2321 datedit_grabber_info[c]->grab = grab_patch;
2322 break;
2323 }
2324 }
2325
2326 if (datedit_grabber_info[c]->type == DAT_END) {
2327 fprintf(stderr, "Argh, patch object not registered!\n");
2328 return 1;
2329 }
2330
2331 for (c=1; c<argc; c++) {
2332 if (argv[c][0] == '-') {
2333 switch (utolower(argv[c][1])) {
2334
2335 case 'b':
2336 if (c >= argc-1) {
2337 usage();
2338 return 1;
2339 }
2340 opt_bank = atoi(argv[++c]);
2341 break;
2342
2343 case 'c':
2344 opt_compression = 1;
2345 break;
2346
2347 case 'd':
2348 if (c >= argc-1) {
2349 usage();
2350 return 1;
2351 }
2352 opt_drum_bank = atoi(argv[++c]);
2353 break;
2354
2355 case 'o':
2356 opt_overwrite = TRUE;
2357 break;
2358
2359 case 'v':
2360 opt_verbose = TRUE;
2361 if (utolower(argv[c][2]) == 'v')
2362 opt_veryverbose = TRUE;
2363 break;
2364
2365 case '8':
2366 opt_8bit = TRUE;
2367 break;
2368
2369 default:
2370 printf("Unknown option '%s'\n", argv[c]);
2371 return 1;
2372 }
2373 }
2374 else {
2375 if (stricmp(get_extension(argv[c]), "dat") == 0) {
2376 if (opt_datafile) {
2377 usage();
2378 return 1;
2379 }
2380 opt_datafile = argv[c];
2381 }
2382 else if (stricmp(get_extension(argv[c]), "mid") == 0) {
2383 if (opt_numnames < MAX_FILES)
2384 opt_namelist[opt_numnames++] = argv[c];
2385 }
2386 else if (stricmp(get_extension(argv[c]), "cfg") == 0) {
2387 if ((opt_configfile) || (opt_soundfont)) {
2388 usage();
2389 return 1;
2390 }
2391 opt_configfile = argv[c];
2392 }
2393 else if (stricmp(get_extension(argv[c]), "sf2") == 0) {
2394 if ((opt_configfile) || (opt_soundfont)) {
2395 usage();
2396 return 1;
2397 }
2398 opt_soundfont = argv[c];
2399 }
2400 else {
2401 printf("Unknown file type '.%s'\n", get_extension(argv[c]));
2402 return 1;
2403 }
2404 }
2405 }
2406
2407 if (!opt_datafile) {
2408 usage();
2409 return 1;
2410 }
2411
2412 if (!opt_overwrite) {
2413 if (file_exists(opt_datafile, FA_RDONLY | FA_ARCH, NULL)) {
2414 printf("%s already exists: use -o to overwrite\n", opt_datafile);
2415 return 1;
2416 }
2417 }
2418
2419 if (opt_numnames == 0) {
2420 printf("No MIDI files specified: including entire patch set\n");
2421
2422 for (c=0; c<128; c++)
2423 need_patches[c] = TRUE;
2424
2425 for (c=35; c<82; c++)
2426 need_drums[c] = TRUE;
2427 }
2428 else {
2429 need_patches[0] = TRUE; /* always load the piano */
2430
2431 for (c=0; c<opt_numnames; c++) {
2432 if (for_each_file_ex(opt_namelist[c], 0, ~(FA_ARCH | FA_RDONLY), read_midi, NULL) <= 0) {
2433 fprintf(stderr, "Error: %s not found\n", opt_namelist[c]);
2434 err = 1;
2435 break;
2436 }
2437 }
2438 }
2439
2440 if (!err) {
2441 if (opt_verbose) {
2442 if (!opt_veryverbose)
2443 printf("\n");
2444
2445 printf("Required patches:\n\n");
2446
2447 for (c=0; c<128; c++)
2448 if (need_patches[c])
2449 printf("\tInstrument #%-6d(%s)\n", c+1, patch_names[c]);
2450
2451 for (c=0; c<128; c++)
2452 if (need_drums[c])
2453 printf("\tPercussion #%-6d(%s)\n", c+1, (((c >= 35) && (c <= 81)) ? drum_names[c-35] : "unknown"));
2454
2455 printf("\n");
2456 }
2457
2458 datafile = _AL_MALLOC(sizeof(DATAFILE));
2459 datafile->dat = NULL;
2460 datafile->type = DAT_END;
2461 datafile->size = 0;
2462 datafile->prop = NULL;
2463
2464 if (opt_soundfont)
2465 add_soundfont_patches();
2466 else
2467 add_gus_patches();
2468
2469 if (!err) {
2470 DATEDIT_SAVE_DATAFILE_OPTIONS options;
2471
2472 options.pack = opt_compression;
2473 options.strip = 1;
2474 options.sort = 1;
2475 options.verbose = (opt_veryverbose || (opt_verbose && opt_compression));
2476 options.write_msg = TRUE;
2477 options.backup = FALSE;
2478
2479 if (!datedit_save_datafile(datafile, opt_datafile, NULL, &options, NULL))
2480 err = 1;
2481 }
2482
2483 unload_datafile(datafile);
2484
2485 if (!err) {
2486 int ok = TRUE;
2487
2488 for (c=0; c<128; c++) {
2489 if (need_patches[c]) {
2490 if (ok) {
2491 printf("\n");
2492 ok = FALSE;
2493 }
2494 printf("Warning: can't find instrument #%d (%s)\n", c+1, patch_names[c]);
2495 }
2496 }
2497
2498 for (c=0; c<128; c++) {
2499 if (need_drums[c]) {
2500 if (ok) {
2501 printf("\n");
2502 ok = FALSE;
2503 }
2504 printf("Warning: can't find percussion #%d (%s)\n", c+1, (((c >= 35) && (c <= 81)) ? drum_names[c-35] : "unknown"));
2505 }
2506 }
2507 }
2508
2509 if ((!err) && (opt_verbose)) {
2510 printf("\nEither specify this file with the \"patches=\" line in your allegro.cfg, or\n");
2511 printf("rename it to patches.dat and put it in the same directory as your program.\n");
2512 }
2513 }
2514
2515 return err;
2516 }
2517
2518 END_OF_MAIN()
2519