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, &params);
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, &params);
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, &params);
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