diff options
Diffstat (limited to 'sys/i386/isa/sound/gustest/gmod.c')
-rw-r--r-- | sys/i386/isa/sound/gustest/gmod.c | 1589 |
1 files changed, 0 insertions, 1589 deletions
diff --git a/sys/i386/isa/sound/gustest/gmod.c b/sys/i386/isa/sound/gustest/gmod.c deleted file mode 100644 index d730e26..0000000 --- a/sys/i386/isa/sound/gustest/gmod.c +++ /dev/null @@ -1,1589 +0,0 @@ -/* - * gmod.c - Module player for GUS and Linux. - * (C) Hannu Savolainen, 1993 - * - * NOTE! This program doesn't try to be a complete module player. - * It's just a too I used while developing the driver. In - * addition it can be used as an example on programming - * the LInux Sound Driver with GUS. - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <sys/ultrasound.h> -#include <sys/ioctl.h> -#include <fcntl.h> -#include <math.h> -#include <string.h> - -#define CMD_ARPEG 0x00 -#define CMD_SLIDEUP 0x01 -#define CMD_SLIDEDOWN 0x02 -#define CMD_SLIDETO 0x03 -#define SLIDE_SIZE 8 -#define CMD_VOLSLIDE 0x0a -#define CMD_JUMP 0x0b -#define CMD_VOLUME 0x0c -#define CMD_BREAK 0x0d -#define CMD_SPEED 0x0f -#define CMD_NOP 0xfe -#define CMD_NONOTE 0xff - -#define MIN(a, b) ((a) < (b) ? (a) : (b)) - -#define MAX_TRACK 8 -#define MAX_PATTERN 128 -#define MAX_POSITION 128 - -struct note_info - { - unsigned char note; - unsigned char vol; - unsigned char sample; - unsigned char command; - short parm1, parm2; - }; - -struct voice_info - { - int sample; - int note; - int volume; - int pitchbender; - - /* Pitch sliding */ - - int slide_pitch; - int slide_goal; - int slide_rate; - - int volslide; - }; - -typedef struct note_info pattern[MAX_TRACK][64]; -int pattern_len[MAX_POSITION]; -int pattern_tempo[MAX_POSITION]; -pattern *pattern_table[MAX_PATTERN]; - -struct voice_info voices[MAX_TRACK]; - -int nr_channels, nr_patterns, songlength; -int tune[MAX_POSITION]; -double tick_duration; - -int period_table[] = -{ - 856, 808, 762, 720, 678, 640, 604, 570, 538, 508, 480, 453, - 428, 404, 381, 360, 339, 320, 302, 285, 269, 254, 240, 226, - 214, 202, 190, 180, 170, 160, 151, 143, 135, 127, 120, 113 -}; - -SEQ_DEFINEBUF (2048); - -int seqfd; -int sample_ok[128], sample_vol[128]; -int tmp, gus_dev; -double this_time, next_time; -int ticks_per_division; -double clock_rate; /* HZ */ - -/* - * The function seqbuf_dump() must always be provided - */ - -void play_module (char *name); -int load_module (char *name); -int play_note (int channel, struct note_info *pat); -void lets_play_voice (int channel, struct voice_info *v); - -void -seqbuf_dump () -{ - if (_seqbufptr) - if (write (seqfd, _seqbuf, _seqbufptr) == -1) - { - perror ("write /dev/sequencer"); - exit (-1); - } - _seqbufptr = 0; -} - -void -init_voices () -{ - int i; - - for (i = 0; i < MAX_TRACK; i++) - { - voices[i].sample = 0; - voices[i].note = 0; - voices[i].volume = 64; - - voices[i].slide_pitch = 0; - voices[i].slide_goal = 0; - voices[i].slide_rate = 0; - voices[i].pitchbender = 0; - - voices[i].volslide = 0; - } -} - -int -main (int argc, char *argv[]) -{ - int i, n, j; - struct synth_info info; - - if ((seqfd = open ("/dev/sequencer", O_WRONLY, 0)) == -1) - { - perror ("/dev/sequencer"); - exit (-1); - } - - if (ioctl (seqfd, SNDCTL_SEQ_NRSYNTHS, &n) == -1) - { - perror ("/dev/sequencer"); - exit (-1); - } - - for (i = 0; i < n; i++) - { - info.device = i; - - if (ioctl (seqfd, SNDCTL_SYNTH_INFO, &info) == -1) - { - perror ("/dev/sequencer"); - exit (-1); - } - - if (info.synth_type == SYNTH_TYPE_SAMPLE - && info.synth_subtype == SAMPLE_TYPE_GUS) - gus_dev = i; - } - - if (gus_dev == -1) - { - fprintf (stderr, "Gravis Ultrasound not detected\n"); - exit (-1); - } - - GUS_NUMVOICES (gus_dev, 14); - - for (i = 1; i < argc; i++) - { - for (j = 0; j < MAX_PATTERN; j++) - pattern_table[j] = NULL; - - if (load_module (argv[i])) - { - tick_duration = 100.0 / clock_rate; - play_module (argv[i]); - } - - } - - SEQ_DUMPBUF (); - close (seqfd); - - exit (0); -} - -unsigned short -intelize (unsigned short v) -{ - return ((v & 0xff) << 8) | ((v >> 8) & 0xff); -} - -unsigned long -intelize4 (unsigned long v) -{ - return - (((v >> 16) & 0xff) << 8) | (((v >> 16) >> 8) & 0xff) | - (((v & 0xff) << 8) | ((v >> 8) & 0xff) << 16); -} - -int -load_stm_module (int mod_fd, char *name) -{ - - struct sample_header - { - char name[12]; - unsigned char instr_disk; - unsigned short reserved1; - unsigned short length; /* In bytes */ - unsigned short loop_start; - unsigned short loop_end; - unsigned char volume; - unsigned char reserved2; - unsigned short C2_speed; - unsigned short reserved3; - - }; - - int i, total_mem; - int sample_ptr; - - int position; - - unsigned char *tune_ptr; /* array 0-127 */ - - char header[1105], sname[21]; - - int nr_samples; /* 16 or 32 samples (or 64 or ???) */ - int slen, npat; - - fprintf (stderr, "Loading .STM module: %s\n", name); - - if (read (mod_fd, header, sizeof (header)) != sizeof (header)) - { - fprintf (stderr, "%s: Short file (header)\n", name); - close (mod_fd); - return 0; - } - - strncpy (sname, header, 20); - - fprintf (stderr, "\nModule: %s - ", sname); - - if (header[28] != 0x1a) - { - fprintf (stderr, "Not a STM module\n"); - close (mod_fd); - return 0; - } - - npat = header[33]; - slen = 0; - tune_ptr = &header[48 + (31 * 32)]; - - for (i = 0; i < 64; i++) - { - tune[i] = tune_ptr[i]; - if (tune[i] < npat) - slen = i; - } - - fprintf (stderr, "Song lenght %d, %d patterns.\n", slen, npat); - - nr_samples = 31; - - sample_ptr = 48 + (31 * 32) + 64 + (npat * 1024); /* Location where the - * first sample is - * stored */ - total_mem = 0; - - for (i = 0; i < 32; i++) - sample_ok[i] = 0; - - for (i = 0; i < nr_samples; i++) - { - int len, loop_start, loop_end, base_freq; - unsigned short loop_flags = 0; - - struct sample_header *sample; - - struct patch_info *patch; - - sample = (struct sample_header *) &header[48 + (i * 32)]; - - len = sample->length; - loop_start = sample->loop_start; - loop_end = sample->loop_end; - base_freq = sample->C2_speed; - - if (strlen (sample->name) > 21) - { - fprintf (stderr, "\nInvalid name for sample #%d\n", i); - close (mod_fd); - return 0; - } - - if (len > 0) - { - int x; - - if (loop_end > len) - loop_end = 1; - else if (loop_end < loop_start) - { - loop_start = 0; - loop_end = 0; - } - else - loop_flags = WAVE_LOOPING; - - total_mem += len; - patch = (struct patch_info *) malloc (sizeof (*patch) + len); - - patch->key = GUS_PATCH; - patch->device_no = gus_dev; - patch->instr_no = i; - patch->mode = loop_flags; - patch->len = len; - patch->loop_start = loop_start; - patch->loop_end = loop_end; - patch->base_freq = base_freq; - patch->base_note = 261630; /* Mid C */ - patch->low_note = 0; - patch->high_note = 0x7fffffff; - patch->volume = 120; - - if (lseek (mod_fd, sample_ptr, 0) == -1) - { - perror (name); - close (mod_fd); - free (patch); - return 0; - } - - sample_ptr += len; - - if ((x = read (mod_fd, patch->data, len)) != len) - { - fprintf (stderr, "Short file (sample at %d (%d!=%d)\n", sample_ptr, x, len); - close (mod_fd); - free (patch); - return 0; - } - - fprintf (stderr, "Sample %02d: %05d, %05d, %05d, %07d %s\n", - i, - len, - loop_start, - loop_end, - base_freq, - sample->name); - - if (write (seqfd, patch, sizeof (*patch) + len) == -1) - { - perror ("ioctl /dev/sequencer"); - exit (-1); - } - else - sample_ok[i] = 1; - - free (patch); - } - } - - nr_patterns = slen; - songlength = slen; - nr_channels = 4; - - for (position = 0; position < npat; position++) - { - unsigned char patterns[64][4][4]; - int pat, channel, x; - - int pp = 1104 + (position * 1024); - - if ((pattern_table[position] = (pattern *) malloc (sizeof (struct note_info) * 64 * nr_channels)) == NULL) - { - fprintf (stderr, "Can't allocate memory for a pattern\n"); - return 0; - } - - if (lseek (mod_fd, pp, 0) == -1) - { - perror (name); - close (mod_fd); - return 0; - } - - if ((x = read (mod_fd, patterns, 1024)) != 1024) - { - fprintf (stderr, "Short file (pattern at %d), %d!=%d\n", pp, x, 1024); - close (mod_fd); - return 0; - } - - for (pat = 0; pat < 64; pat++) - { - - for (channel = 0; channel < 4; channel++) - { - unsigned char *p; - - unsigned vol, note, octave, sample, effect, params; - - p = &patterns[pat][channel][0]; - - if (p[0] < 251) - { - note = p[0] & 15; - octave = p[0] / 16; - - note = 48 + octave * 12 + note; - - sample = p[1] / 8; - vol = (p[1] & 7) + (p[2] / 2); - effect = p[2] & 0xF; - params = p[3]; - } - else - { - note = 0; - octave = 0; - - sample = 0; - vol = 0; - effect = CMD_NONOTE; - params = 0; - } - - (*pattern_table[position])[channel][pat].note = note; - (*pattern_table[position])[channel][pat].sample = sample; - (*pattern_table[position])[channel][pat].command = effect; - (*pattern_table[position])[channel][pat].parm1 = params; - (*pattern_table[position])[channel][pat].parm2 = 0; - (*pattern_table[position])[channel][pat].vol = vol; - } - - } - - } - - close (mod_fd); - return 1; -} - -int -load_669_module (int mod_fd, char *name) -{ - struct sample_header - { - char name[13]; - unsigned long length; /* In bytes */ - unsigned long loop_start; - unsigned long loop_end; - }; - - int i, total_mem; - int sample_ptr; - - int position; - - unsigned char *tune_ptr, *len_ptr, *tempo_ptr; /* array 0-127 */ - - char header[1084]; - char msg[110]; - - int nr_samples; /* 16 or 32 samples */ - int slen, npat; - - clock_rate = 25.0; - - fprintf (stderr, "Loading .669 module: %s\n", name); - - if (read (mod_fd, header, sizeof (header)) != sizeof (header)) - { - fprintf (stderr, "%s: Short file (header)\n", name); - close (mod_fd); - return 0; - } - - if (*(unsigned short *) &header[0] != 0x6669) - { - fprintf (stderr, "Not a 669 file\n"); - close (mod_fd); - return 0; - } - - strncpy (msg, &header[2], 108); - - for (i = 0; i < strlen (msg); i++) - if ((msg[i] >= ' ' && msg[i] <= 'z') || msg[i] == '\n') - printf ("%c", msg[i]); - printf ("\n"); - - npat = header[0x6f]; - - tune_ptr = &header[0x71]; - - for (slen = 0; slen < 128 && tune_ptr[slen] != 0xff; slen++); - slen--; - - for (i = 0; i < slen; i++) - tune[i] = tune_ptr[i]; - - len_ptr = &header[0x171]; - for (i = 0; i < slen; i++) - pattern_len[i] = len_ptr[i] - 1; - - tempo_ptr = &header[0xf1]; - for (i = 0; i < slen; i++) - pattern_tempo[i] = tempo_ptr[i]; - - nr_samples = header[0x6e]; - - fprintf (stderr, "Song lenght %d, %d patterns, %d samples.\n", slen, npat, nr_samples); - - sample_ptr = 0x1f1 + (nr_samples * 0x19) + (npat * 0x600); /* Location where the - * first sample is - * stored */ - total_mem = 0; - - for (i = 0; i < 64; i++) - sample_ok[i] = 0; - - for (i = 0; i < nr_samples; i++) - { - int len, loop_start, loop_end; - unsigned short loop_flags = 0; - - struct sample_header *sample; - char sname[14]; - - struct patch_info *patch; - - sample = (struct sample_header *) &header[0x1f1 + (i * 0x19)]; - - len = *(unsigned long *) &sample->name[13]; - loop_start = *(unsigned long *) &sample->name[17]; - loop_end = *(unsigned long *) &sample->name[21]; - if (loop_end > len) - loop_end = 1; - else if (loop_end == len) - loop_end--; - - if (loop_end < loop_start) - { - loop_start = 0; - loop_end = 0; - } - - strncpy (sname, sample->name, 13); - - if (len > 0 && len < 200000) - { - total_mem += len; - - fprintf (stderr, "Sample %02d: %05d, %05d, %05d %s\n", - i, - len, - loop_start, - loop_end, - sname); - - patch = (struct patch_info *) malloc (sizeof (*patch) + len); - - if (loop_end == 0) - loop_end = 1; - if (loop_end >= len) - loop_end = 1; - - if (loop_end > 1) loop_flags = WAVE_LOOPING; - - patch->key = GUS_PATCH; - patch->device_no = gus_dev; - patch->instr_no = i; - patch->mode = WAVE_UNSIGNED | loop_flags; - patch->len = len; - patch->loop_start = loop_start; - patch->loop_end = loop_end; - patch->base_freq = 8448; - patch->base_note = 261630; - patch->low_note = 1000; - patch->high_note = 0x7fffffff; - patch->volume = 120; - - if (lseek (mod_fd, sample_ptr, 0) == -1) - { - fprintf (stderr, "Seek failed\n"); - perror (name); - close (mod_fd); - free (patch); - return 0; - } - - sample_ptr += len; - - if (read (mod_fd, patch->data, len) != len) - { - fprintf (stderr, "Short file (sample at %d)\n", sample_ptr); - close (mod_fd); - free (patch); - return 0; - } - - if (write (seqfd, patch, sizeof (*patch) + len) == -1) - { - perror ("ioctl /dev/sequencer"); - /* exit (-1); */ - } - else - sample_ok[i] = 1; - - free (patch); - } - } - - nr_patterns = slen; - songlength = slen; - nr_channels = 8; - - for (position = 0; position < npat; position++) - { - unsigned char patterns[0x600]; - int pat, channel, x; - - int pp = 0x1f1 + (nr_samples * 0x19) + (position * 0x600); - - if ((pattern_table[position] = (pattern *) malloc (sizeof (struct note_info) * 64 * nr_channels)) == NULL) - { - fprintf (stderr, "Can't allocate memory for a pattern\n"); - return 0; - } - - - if (lseek (mod_fd, pp, 0) == -1) - { - perror (name); - close (mod_fd); - return 0; - } - - if ((x = read (mod_fd, patterns, 1024)) != 1024) - { - fprintf (stderr, "Short file (pattern at %d) %d!=1024\n", pp, x); - close (mod_fd); - return 0; - } - - for (pat = 0; pat < 64; pat++) - { - - for (channel = 0; channel < 8; channel++) - { - unsigned char *p; - - unsigned vol, period, sample, effect, params; - - p = &patterns[pat * 24 + channel * 3]; - - if (p[0] >= 0xfe || - (p[0] == 0xff && p[1] == 0xff && p[2] == 0xff) || - (p[0] == 0 && p[1] == 0 && p[2] == 0) || - *(int *) p == -1) - { - period = 0; - effect = CMD_NONOTE; - sample = 0; - vol = 0; - params = 0; - - if (p[0] == 0) - { - effect = CMD_BREAK; - params = -2; - } - } - else - { - period = (p[0] >> 2) + 48; - effect = (p[2] >> 4); - params = p[2] & 0x0f; - vol = p[1] & 0x0f; - - if (p[2] == 0xfe) - { - effect = CMD_VOLUME; - params = vol; - } - else if (p[2] == 0xff) - { - effect = CMD_NOP; - } - else - switch (effect) - { - case 0: /* a - Portamento up */ - effect = CMD_SLIDEUP; - break; - - case 1: /* b - Portamento down */ - effect = CMD_SLIDEDOWN; - break; - - case 2: /* c - Port to note */ - effect = CMD_SLIDETO; - break; - - case 3: /* d - Frequency adjust */ - effect = CMD_NOP; /* To be implemented */ - break; - - case 4: /* e - Frequency vibrato */ - effect = CMD_NOP; /* To be implemented */ - break; - - case 5: /* f - Set tempo */ - effect = CMD_SPEED; - break; - - default: - effect = CMD_NOP; - } - - sample = (((p[0] << 4) & 0x30) | ((p[1] >> 4) & 0x0f)) + 1; - } - - (*pattern_table[position])[channel][pat].note = period; - (*pattern_table[position])[channel][pat].sample = sample; - (*pattern_table[position])[channel][pat].command = effect; - (*pattern_table[position])[channel][pat].parm1 = params; - (*pattern_table[position])[channel][pat].parm2 = 0; - (*pattern_table[position])[channel][pat].vol = vol; - } - - } - - } - - close (mod_fd); - return 1; -} - -int -load_mmd0_module (int mod_fd, char *name) -{ - - struct sample_header - { - unsigned short loop_start; - unsigned short loop_end; - unsigned char midich; - unsigned char midipreset; - unsigned char volume; - unsigned char strans; - }; - - int i, total_mem; - int sample_ptr; - - int position; - - unsigned char *tune_ptr; /* array 0-127 */ - - char header[1105]; - - int nr_samples; /* 16 or 32 samples (or 64 or ???) */ - int slen, npat; - - fprintf (stderr, "Loading .MED module: %s\n", name); - - if (read (mod_fd, header, sizeof (header)) != sizeof (header)) - { - fprintf (stderr, "%s: Short file (header)\n", name); - close (mod_fd); - return 0; - } - - if (strncmp (header, "MMD0", 4)) - { - fprintf (stderr, "Not a MED module\n"); - close (mod_fd); - return 0; - } - - printf ("Module len %d\n", intelize4 (*(long *) &header[4])); - printf ("Song info %d\n", intelize4 (*(long *) &header[8])); - printf ("Song len %d\n", intelize4 (*(long *) &header[12])); - printf ("Blockarr %x\n", intelize4 (*(long *) &header[16])); - printf ("Blockarr len %d\n", intelize4 (*(long *) &header[20])); - printf ("Sample array %x\n", intelize4 (*(long *) &header[24])); - printf ("Sample array len %d\n", intelize4 (*(long *) &header[28])); - printf ("Exp data %x\n", intelize4 (*(long *) &header[32])); - printf ("Exp size %d\n", intelize4 (*(long *) &header[36])); - printf ("Pstate %d\n", intelize (*(long *) &header[40])); - printf ("Pblock %d\n", intelize (*(long *) &header[42])); - - return 0; - - npat = header[33]; - slen = 0; - tune_ptr = &header[48 + (31 * 32)]; - - for (i = 0; i < 64; i++) - { - tune[i] = tune_ptr[i]; - if (tune[i] < npat) - slen = i; - } - - fprintf (stderr, "Song lenght %d, %d patterns.\n", slen, npat); - - nr_samples = 31; - - sample_ptr = 48 + (31 * 32) + 64 + (npat * 1024); /* Location where the - * first sample is - * stored */ - total_mem = 0; - - for (i = 0; i < 32; i++) - sample_ok[i] = 0; - - for (i = 0; i < nr_samples; i++) - { - int len, loop_start, loop_end, base_freq; - unsigned short loop_flags = 0; - - struct sample_header *sample; - - struct patch_info *patch; - - sample = (struct sample_header *) &header[48 + (i * 32)]; - - /* - * len = sample->length; loop_start = sample->loop_start; loop_end = - * sample->loop_end; base_freq = sample->C2_speed; - * - * if (strlen (sample->name) > 21) { fprintf (stderr, "\nInvalid name for - * sample #%d\n", i); close (mod_fd); return 0; } - */ - if (len > 0) - { - int x; - - if (loop_end > len) - loop_end = 1; - - if (loop_end < loop_start) - { - loop_start = 0; - loop_end = 0; - } - - if (loop_end > 2) loop_flags = WAVE_LOOPING; - - total_mem += len; - patch = (struct patch_info *) malloc (sizeof (*patch) + len); - - patch->key = GUS_PATCH; - patch->device_no = gus_dev; - patch->instr_no = i; - patch->mode = loop_flags; - patch->len = len; - patch->loop_start = loop_start; - patch->loop_end = loop_end; - patch->base_freq = base_freq; - patch->base_note = 261630; /* Mid C */ - patch->low_note = 0; - patch->high_note = 0x7fffffff; - patch->volume = 120; - - if (lseek (mod_fd, sample_ptr, 0) == -1) - { - perror (name); - close (mod_fd); - free (patch); - return 0; - } - - sample_ptr += len; - - if ((x = read (mod_fd, patch->data, len)) != len) - { - fprintf (stderr, "Short file (sample at %d (%d!=%d)\n", sample_ptr, x, len); - close (mod_fd); - free (patch); - return 0; - } - /* - * fprintf (stderr, "Sample %02d: %05d, %05d, %05d, %07d %s\n", i, - * len, loop_start, loop_end, base_freq, sample->name); - */ - if (write (seqfd, patch, sizeof (*patch) + len) == -1) - { - perror ("ioctl /dev/sequencer"); - exit (-1); - } - else - sample_ok[i] = 1; - - free (patch); - } - } - - nr_patterns = slen; - songlength = slen; - nr_channels = 4; - - for (position = 0; position < npat; position++) - { - unsigned char patterns[64][4][4]; - int pat, channel, x; - - int pp = 1104 + (position * 1024); - - if ((pattern_table[position] = (pattern *) malloc (sizeof (struct note_info) * 64 * nr_channels)) == NULL) - { - fprintf (stderr, "Can't allocate memory for a pattern\n"); - return 0; - } - - if (lseek (mod_fd, pp, 0) == -1) - { - perror (name); - close (mod_fd); - return 0; - } - - if ((x = read (mod_fd, patterns, 1024)) != 1024) - { - fprintf (stderr, "Short file (pattern at %d), %d!=%d\n", pp, x, 1024); - close (mod_fd); - return 0; - } - - for (pat = 0; pat < 64; pat++) - { - - for (channel = 0; channel < 4; channel++) - { - unsigned char *p; - - unsigned vol, note, octave, sample, effect, params; - - p = &patterns[pat][channel][0]; - - if (p[0] < 251) - { - note = p[0] & 15; - octave = p[0] / 16; - - note = 48 + octave * 12 + note; - - sample = p[1] / 8; - vol = (p[1] & 7) + (p[2] / 2); - effect = p[2] & 0xF; - params = p[3]; - } - else - { - note = 0; - octave = 0; - - sample = 0; - vol = 0; - effect = CMD_NONOTE; - params = 0; - } - - (*pattern_table[position])[channel][pat].note = note; - (*pattern_table[position])[channel][pat].sample = sample; - (*pattern_table[position])[channel][pat].command = effect; - (*pattern_table[position])[channel][pat].parm1 = params; - (*pattern_table[position])[channel][pat].parm2 = 0; - (*pattern_table[position])[channel][pat].vol = vol; - } - - } - - } - - close (mod_fd); - return 1; -} - -int -load_module (char *name) -{ - - struct sample_header - { - char name[22]; - unsigned short length; /* In words */ - - unsigned char finetune; - unsigned char volume; - - unsigned short repeat_point; /* In words */ - unsigned short repeat_length; /* In words */ - }; - - int i, mod_fd, total_mem; - int sample_ptr, pattern_loc; - - int position; - - unsigned char *tune_ptr; /* array 0-127 */ - - char header[1084]; - - int nr_samples; /* 16 or 32 samples */ - int slen, npat; - char mname[23]; - - ioctl (seqfd, SNDCTL_SEQ_SYNC, 0); - ioctl (seqfd, SNDCTL_SEQ_RESETSAMPLES, &gus_dev); - - clock_rate = 50.0; - - for (i = 0; i < MAX_POSITION; i++) - pattern_len[i] = 64; - - for (i = 0; i < MAX_POSITION; i++) - pattern_tempo[i] = 0; - - if ((mod_fd = open (name, O_RDONLY, 0)) == -1) - { - perror (name); - return 0; - } - - if (read (mod_fd, header, sizeof (header)) != sizeof (header)) - { - fprintf (stderr, "%s: Short file (header)\n", name); - close (mod_fd); - return 0; - } - - if (lseek (mod_fd, 0, 0) == -1) - { - perror (name); - close (mod_fd); - return 0; - } - - if (header[28] == 0x1a) - return load_stm_module (mod_fd, name); - - if (*(unsigned short *) &header[0] == 0x6669) - return load_669_module (mod_fd, name); - - if (!strncmp (header, "MMD0", 4)) - return load_mmd0_module (mod_fd, name); - - fprintf (stderr, "Loading .MOD module: %s\n", name); - - strncpy (mname, header, 22); - fprintf (stderr, "\nModule: %s - ", mname); - - if (!strncmp (&header[1080], "M.K.", 4) || !strncmp (&header[1080], "FLT8", 4)) - { - fprintf (stderr, "31 samples\n"); - nr_samples = 31; - } - else - { - fprintf (stderr, "15 samples\n"); - nr_samples = 15; - } - - if (nr_samples == 31) - { - sample_ptr = pattern_loc = 1084; - slen = header[950]; - tune_ptr = (unsigned char *) &header[952]; - } - else - { - sample_ptr = pattern_loc = 600; - slen = header[470]; - tune_ptr = (unsigned char *) &header[472]; - } - - npat = 0; - for (i = 0; i < 128; i++) - { - tune[i] = tune_ptr[i]; - - if (tune_ptr[i] > npat) - npat = tune_ptr[i]; - } - npat++; - - fprintf (stderr, "Song lenght %d, %d patterns.\n", slen, npat); - - sample_ptr += (npat * 1024); /* Location where the first sample is stored */ - total_mem = 0; - - for (i = 0; i < 32; i++) - sample_ok[i] = 0; - - for (i = 0; i < nr_samples; i++) - { - int len, loop_start, loop_end; - unsigned short loop_flags = 0; - char pname[22]; - - struct sample_header *sample; - - struct patch_info *patch; - - sample = (struct sample_header *) &header[20 + (i * 30)]; - - len = intelize (sample->length) * 2; - loop_start = intelize (sample->repeat_point) * 2; - loop_end = loop_start + (intelize (sample->repeat_length) * 2); - - if (loop_start > len) - loop_start = 0; - if (loop_end > len) - loop_end = len; - - if (loop_end <= loop_start) - loop_end = loop_start + 1; - - if (loop_end > 2 && loop_end > loop_start) - loop_flags = WAVE_LOOPING; - - strncpy (pname, sample->name, 20); - - if (len > 0) - { - fprintf (stderr, "Sample %02d: L%05d, S%05d, E%05d V%02d %s\n", - i, - len, - loop_start, - loop_end, - sample->volume, - pname); - - total_mem += len; - - patch = (struct patch_info *) malloc (sizeof (*patch) + len); - - patch->key = GUS_PATCH; - patch->device_no = gus_dev; - patch->instr_no = i; - patch->mode = loop_flags; - patch->len = len; - patch->loop_start = loop_start; - patch->loop_end = loop_end; - patch->base_note = 261630; /* Middle C */ - patch->base_freq = 8448; - patch->low_note = 0; - patch->high_note = 20000000; - patch->volume = 120; - patch->panning = 0; - - if (lseek (mod_fd, sample_ptr, 0) == -1) - { - perror (name); - close (mod_fd); - free (patch); - return 0; - } - - sample_ptr += len; - - if (read (mod_fd, patch->data, len) != len) - { - fprintf (stderr, "Short file (sample) %d\n", sample_ptr); - close (mod_fd); - free (patch); - return 0; - } - - SEQ_WRPATCH (patch, sizeof (*patch) + len); - - sample_ok[i] = 1; - if (sample->volume == 0) sample->volume = 64; - sample_vol[i] = sample->volume; - - free (patch); - } - } - - nr_patterns = npat; - songlength = slen; - nr_channels = 4; - - for (position = 0; position < npat; position++) - { - unsigned char patterns[64][4][4]; - int pat, channel; - - int pp = pattern_loc + (position * 1024); - - if (lseek (mod_fd, pp, 0) == -1) - { - perror (name); - close (mod_fd); - return 0; - } - - if (read (mod_fd, patterns, 1024) != 1024) - { - fprintf (stderr, "Short file (pattern %d) %d\n", tune[position], pp); - close (mod_fd); - return 0; - } - - if ((pattern_table[position] = (pattern *) malloc (sizeof (struct note_info) * 64 * nr_channels)) == NULL) - { - fprintf (stderr, "Can't allocate memory for a pattern\n"); - return 0; - } - - for (pat = 0; pat < 64; pat++) - { - for (channel = 0; channel < 4; channel++) - { - unsigned short tmp; - unsigned char *p; - - unsigned period, sample, effect, params, note, vol; - - p = &patterns[pat][channel][0]; - - tmp = (p[0] << 8) | p[1]; - sample = (tmp >> 8) & 0x10; - period = - MIN (tmp & 0xFFF, 1023); - tmp = (p[2] << 8) | p[3]; - sample |= tmp >> 12; - effect = (tmp >> 8) & 0xF; - params = tmp & 0xFF; - - note = 0; - - if (period) - { - /* - * Convert period to a Midi note number - */ - - for (note = 0; note < 37 && period != period_table[note]; note++); - if (note >= 37) - note = 0; - - note += 48; - } - - vol = 64; - - if (sample) - if (effect == 0xc) - { - vol = params; - } - else - vol = sample_vol[sample - 1]; - - vol *= 2; - if (vol>64)vol--; - - (*pattern_table[position])[channel][pat].note = note; - (*pattern_table[position])[channel][pat].sample = sample; - (*pattern_table[position])[channel][pat].command = effect; - (*pattern_table[position])[channel][pat].parm1 = params; - (*pattern_table[position])[channel][pat].parm2 = 0; - (*pattern_table[position])[channel][pat].vol = vol; - } - } - } - - close (mod_fd); - return 1; -} - -int -panning (int ch) -{ - static int panning_tab[] = - {-110, 110, 110, -110}; - - return panning_tab[ch % 4]; -} - -void -set_speed (int parm) -{ - if (!parm) - parm = 1; - - if (parm < 32) - { - ticks_per_division = parm; - } - else - { - tick_duration = (60.0 / parm) * 10.0; - } - -} - -void -play_module (char *name) -{ - int i, position, jump_to_pos; - - init_voices (); - - SEQ_START_TIMER (); -#if 1 - for (i=0;i<32;i++) - { - SEQ_EXPRESSION(gus_dev, i, 127); - SEQ_MAIN_VOLUME(gus_dev, i, 100); - } -#endif - next_time = 0.0; - - set_speed (6); - - for (position = 0; position < songlength; position++) - { - int tick, pattern, channel, pos, go_to; - - pos = tune[position]; - if (pattern_tempo[position]) - set_speed (pattern_tempo[position]); - - jump_to_pos = -1; - for (pattern = 0; pattern < pattern_len[position] && jump_to_pos == -1; pattern++) - { - this_time = 0.0; - - for (channel = 0; channel < nr_channels; channel++) - { - if ((go_to = play_note (channel, &(*pattern_table[pos])[channel][pattern])) != -1) - jump_to_pos = go_to; - - } - - next_time += tick_duration; - - for (tick = 1; tick < ticks_per_division; tick++) - { - for (channel = 0; channel < nr_channels; channel++) - lets_play_voice (channel, &voices[channel]); - next_time += tick_duration; - } - - } - - if (jump_to_pos >= 0) - position = jump_to_pos; - } - - SEQ_WAIT_TIME ((int) next_time + 200); /* Wait extra 2 secs */ - - for (i = 0; i < nr_channels; i++) - SEQ_STOP_NOTE (gus_dev, i, 0, 127); - SEQ_DUMPBUF (); - - for (i = 0; i < nr_patterns; i++) - free (pattern_table[i]); -} - -void -sync_time () -{ - if (next_time > this_time) - { - SEQ_WAIT_TIME ((long) next_time); - this_time = next_time; - } -} - -void -set_volslide (int channel, struct note_info *pat) -{ - int n; - - voices[channel].volslide = 0; - - if ((n = (pat->parm1 & 0xf0) >> 4)) - voices[channel].volslide = n; - else - voices[channel].volslide = pat->parm1 & 0xf; -} - -void -set_slideto (int channel, struct note_info *pat) -{ - int size, rate, dir, range = 200; - - rate = pat->parm1; - size = voices[channel].note - pat->note; - if (!size) - return; - - if (size < 0) - { - size *= -1; - dir = -1; - } - else - dir = 1; - - if (size > 2) - { - range = size * 100; - rate = rate * size / 200; - } - - rate = pat->parm1 * dir / 30; - if (!rate) - rate = 1; - - voices[channel].slide_pitch = 1; - voices[channel].slide_goal = (dir * 8192 * 200 * 2 / size) / range; - voices[channel].pitchbender = 0; - voices[channel].slide_rate = rate; - SEQ_BENDER_RANGE (gus_dev, channel, range); -} - -int -play_note (int channel, struct note_info *pat) -{ - int jump = -1; - int sample; - - if (pat->sample == 0x3f) - pat->sample = 0; - - if (pat->command == CMD_NONOTE) - return -1; /* Undefined */ - - sample = pat->sample; - - if (sample && !pat->note) - { - pat->note = voices[channel].note; - } - - if (sample) - voices[channel].sample = sample; - else - sample = voices[channel].sample; - - sample--; - - if (pat->note && pat->command != 3) /* Have a note -> play */ - { - if (sample < 0) - sample = voices[channel].sample - 1; - - if (!sample_ok[sample]) - sample = voices[channel].sample - 1; - - if (sample < 0) - sample = 0; - - if (sample_ok[sample]) - { - sync_time (); - - if (pat->vol > 127) pat->vol=127; - SEQ_SET_PATCH (gus_dev, channel, sample); - SEQ_PANNING (gus_dev, channel, panning (channel)); - SEQ_PITCHBEND (gus_dev, channel, 0); - SEQ_START_NOTE (gus_dev, channel, pat->note, pat->vol); - - voices[channel].volume = pat->vol; - voices[channel].note = pat->note; - voices[channel].slide_pitch = 0; - } - else - SEQ_STOP_NOTE (gus_dev, channel, pat->note, pat->vol); - } - - switch (pat->command) - { - - case CMD_NOP:; - break; - - case CMD_JUMP: - jump = pat->parm1; - break; - - case CMD_BREAK: - jump = -2; - break; - - case CMD_SPEED: - set_speed (pat->parm1); - break; - - case CMD_SLIDEUP: - voices[channel].slide_pitch = 1; - voices[channel].slide_goal = 8191; - voices[channel].pitchbender = 0; - voices[channel].slide_rate = pat->parm1 * SLIDE_SIZE; - SEQ_BENDER_RANGE (gus_dev, channel, 200); - break; - - case CMD_SLIDEDOWN: - voices[channel].slide_pitch = 1; - voices[channel].slide_goal = -8192; - voices[channel].pitchbender = 0; - voices[channel].slide_rate = -pat->parm1 * SLIDE_SIZE; - SEQ_BENDER_RANGE (gus_dev, channel, 200); - break; - - case CMD_SLIDETO: - set_slideto (channel, pat); - break; - - case CMD_VOLUME: - { - int vol = pat->parm1*2; - if (vol>127) vol=127; - if (pat->note && pat->command != 3) - break; - SEQ_START_NOTE (gus_dev, channel, 255, vol); - } - break; - - case CMD_ARPEG: - break; - - case 0x0e: - /* printf ("Cmd 0xE%02x\n", pat->parm1); */ - break; - - case CMD_VOLSLIDE: - set_slideto (channel, pat); - break; - - default: - /* printf ("Command %x %02x\n", pat->command, pat->parm1); */ - } - - return jump; -} - -void -lets_play_voice (int channel, struct voice_info *v) -{ - if (v->slide_pitch) - { - v->pitchbender += v->slide_rate; - if (v->slide_goal < 0) - { - if (v->pitchbender <= v->slide_goal) - { - v->pitchbender = v->slide_goal; - v->slide_pitch = 0; /* Stop */ - } - } - else - { - if (v->pitchbender >= v->slide_goal) - { - v->pitchbender = v->slide_goal; - v->slide_pitch = 0; /* Stop */ - } - } - - sync_time (); - SEQ_PITCHBEND (gus_dev, channel, v->pitchbender); - } - - if (v->volslide) - { - v->volume += v->volslide; - sync_time (); - - if (v->volume > 127) v->volume = 127; - SEQ_START_NOTE (gus_dev, channel, 255, v->volume); - } -} |