native_midi_gpl/emumidi.c
author Sam Lantinga <slouken@libsdl.org>
Wed, 13 Feb 2002 19:07:39 +0000
changeset 160 c62666b42573
permissions -rw-r--r--
Peter Kutak - Wed Feb 13 10:26:57 PST 2002
* Added native midi support on Linux, using GPL code
--enable-music-native-midi-gpl
     1 /************************************************************************
     2    emumidi.c  -- emulation of midi device for FM/OPL3/GUS
     3 
     4    Copyright (C) 1994-1996 Nathan I. Laredo
     5 
     6    This program is modifiable/redistributable under the terms
     7    of the GNU General Public Licence.
     8 
     9    You should have received a copy of the GNU General Public License
    10    along with this program; if not, write to the Free Software
    11    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
    12    Send your comments and all your spare pocket change to
    13    laredo@gnu.ai.mit.edu (Nathan Laredo) or to PSC 1, BOX 709, 2401
    14    Kelly Drive, Lackland AFB, TX 78236-5128, USA.
    15  *************************************************************************/
    16 /*    edited by Peter Kutak         */
    17 /*    email : kutak@stonline.sk     */
    18 
    19 #if defined(linux) || defined(__FreeBSD__)
    20 
    21 #include "emumidi.h"
    22 
    23 SEQ_USE_EXTBUF();
    24 
    25 extern int seqfd, play_ext, play_gus, play_fm, play_awe;
    26 extern int gus_dev, sb_dev, ext_dev, awe_dev;
    27 extern struct synth_info card_info[MAX_CARDS];
    28 extern int chanmask, perc, ticks, dochan, wantopl3, MT32;
    29 extern int patchloaded[256], fmloaded[256], useprog[16];
    30 int note_vel[16][128];
    31 struct voicestate voice[2][36];
    32 struct chanstate channel[16];
    33 #define C_GUS 0
    34 #define C_FM 1
    35 #define CN (ISGUS(chn) ? C_GUS : C_FM)
    36 #define CHANNEL (dochan ? chn : 0)
    37 
    38 void load_sysex(length, data, type)
    39 int length;
    40 unsigned char *data;
    41 int type;
    42 {
    43     unsigned long int i, j;
    44 
    45     /*
    46      * If the system exclusive is for roland, evaluate it.  More than
    47      * roland could be evaluated here if i had documentation.  Please
    48      * submit patches for any other hardware to laredo@gnu.ai.mit.edu
    49      * Complete emulation of all GS sysex messages in the works....
    50      */
    51     if (length > 7 && data[0] == 0x41 && data[2] == 0x42 && data[3] == 0x12) {
    52 	/* GS DATA SET MESSAGES */
    53 	if (data[4] == 0x40 && (data[5] & 0xf0) == 0x10 && data[6] == 0x15) {
    54 		/* USE RHYTHM PART */
    55 		if (!(i = (data[5] & 0xf)))
    56 		    i = 0x09;
    57 		else if (i < 10)
    58 		    i--;
    59 		i = 1<<i;
    60 		if (data[7])
    61 		    perc |= i;
    62 		else
    63 		    perc &= ~i;
    64 	}
    65 	if ((data[4] == 0x40 || data[4] == 0) &&
    66 	    data[5] == 0x00 && data[6] == 0x7f) { /* GS RESET */
    67 		perc = 0x0200;	/* percussion in channel 10 only */
    68 		for (i = 0; i < 16; i++) {	/* set state info */
    69 		    for (j = 0; j < 128; j++)
    70 			note_vel[i][j] = 0;
    71 		    channel[i].bender = channel[i].oldbend = 8192;
    72 		    channel[i].bender_range = channel[i].oldrange = 2;
    73 		    channel[i].controller[CTL_PAN] = 64;
    74 		    channel[i].controller[CTL_SUSTAIN] = 0;
    75     		}
    76 	}
    77     }
    78     if (!play_ext)
    79 	return;
    80     if (type == MIDI_SYSTEM_PREFIX)
    81 	SEQ_MIDIOUT(ext_dev, MIDI_SYSTEM_PREFIX);
    82     for (i = 0; i < length; i++)
    83 	SEQ_MIDIOUT(ext_dev, data[i]);
    84 }
    85 
    86 int seq_set_patch(chn, pgm)
    87 int chn, pgm;
    88 {
    89     if (MT32 && pgm < 128)
    90 	pgm = mt32pgm[pgm];
    91     if (useprog[chn])
    92 	pgm = useprog[chn] - 1;
    93     if (ISMIDI(chn)) {
    94 	SEQ_MIDIOUT(ext_dev, MIDI_PGM_CHANGE + CHANNEL);
    95 	SEQ_MIDIOUT(ext_dev, pgm);
    96     } else if (ISAWE(chn)) {
    97 	SEQ_SET_PATCH(awe_dev, chn, pgm);
    98     } else if (ISPERC(chn)) {
    99 	if (ISGUS(chn) && patchloaded[pgm] != 1)
   100 	    return -1;
   101 	else if (ISFM(chn) && !fmloaded[pgm])
   102 	    return -1;
   103     } else if (ISGUS(chn) && patchloaded[pgm] != 1)
   104 	/* find first loaded gus program to replace missing one */
   105 	for (pgm = 0; patchloaded[pgm] != 1; pgm++);
   106     return (channel[chn].program = pgm);
   107 }
   108 
   109 /* finetune returns exact frequency with bender applied.  Not used */
   110 /*
   111 int finetune(chn, note)
   112 int chn, note;
   113 {
   114     long int r, b, d;
   115 
   116     r = channel[chn].bender_range;
   117     b = channel[chn].bender - 8192;
   118     if (!b || r + note > 127 || r - note < 0)
   119 	return n_freq[note];
   120     r = n_freq[note + r] - n_freq[note - r];
   121     d = b * r;
   122     d /= 8192;
   123     return n_freq[note] + d;
   124 
   125 }
   126 */
   127 extern int _seqbufptr;
   128 
   129 void seq_stop_note(dev, chn, note, vel)
   130 int dev, chn, note, vel;
   131 {
   132     int i, card = CN;
   133 
   134     note_vel[chn][note] = 0;
   135     if (ISMIDI(chn)) {
   136 	SEQ_MIDIOUT(dev, MIDI_NOTEOFF + CHANNEL);
   137 	SEQ_MIDIOUT(dev, note);
   138 	SEQ_MIDIOUT(dev, vel);
   139     } else if (ISAWE(chn)) {
   140 	SEQ_STOP_NOTE(dev, chn, note, vel);
   141     } else
   142 	for (i = 0; i < card_info[dev].nr_voices; i++)
   143 	    if (voice[card][i].channel == chn &&
   144 		voice[card][i].note == note) {
   145 		voice[card][i].dead = 1;
   146 		voice[card][i].timestamp /= 2;
   147 		if (!channel[chn].controller[CTL_SUSTAIN] && !ISPERC(chn))
   148 		    SEQ_STOP_NOTE(dev, i, note, vel);
   149 	    }
   150 }
   151 
   152 void seq_key_pressure(dev, chn, note, vel)
   153 int dev, chn, note, vel;
   154 {
   155     int i, card = CN;
   156 
   157     if (ISMIDI(chn)) {
   158 	SEQ_MIDIOUT(dev, MIDI_KEY_PRESSURE + CHANNEL);
   159 	SEQ_MIDIOUT(dev, note);
   160 	SEQ_MIDIOUT(dev, vel);
   161     } else if (ISAWE(chn)) {
   162 	AWE_KEY_PRESSURE(dev, chn, note, vel);
   163     } else
   164 	for (i = 0; i < card_info[dev].nr_voices; i++)
   165 	    if (voice[card][i].channel == chn &&
   166 		voice[card][i].note == note)
   167 		SEQ_KEY_PRESSURE(dev, i, note, vel);
   168 }
   169 
   170 int new_voice(dev, chn)
   171 int dev, chn;
   172 {
   173     int i, oldest, last, card = CN;
   174 
   175     if (ISFM(chn) && fmloaded[channel[chn].program] == OPL3_PATCH)
   176 	last = 6;		/* 4-op voice can only use first six voices */
   177     else
   178 	last = card_info[dev].nr_voices;
   179 
   180     for (i = oldest = 0; i < last; i++)
   181 	if (voice[card][i].timestamp < voice[card][oldest].timestamp)
   182 	    oldest = i;
   183     return oldest;
   184 }
   185 
   186 void seq_start_note(dev, chn, note, vel)
   187 int dev, chn, note, vel;
   188 {
   189     int v, c, card = CN;
   190 
   191     note_vel[chn][note] = vel;
   192     if (ISMIDI(chn)) {
   193 	SEQ_MIDIOUT(dev, MIDI_NOTEON + CHANNEL);
   194 	SEQ_MIDIOUT(dev, note);
   195 	SEQ_MIDIOUT(dev, vel);
   196     } else if (vel == 0)
   197 	seq_stop_note(dev, chn, note, 64);
   198     else if (ISAWE(chn)) {
   199 	SEQ_START_NOTE(dev, chn, note, vel);
   200     } else {
   201 	v = new_voice(dev, chn);
   202 	SEQ_SET_PATCH(dev, v, channel[chn].program);
   203 	SEQ_BENDER_RANGE(dev, v, (channel[chn].bender_range * 100));
   204 	SEQ_BENDER(dev, v, channel[chn].bender);
   205 	SEQ_CONTROL(dev, v, CTL_PAN,
   206 		    channel[chn].controller[CTL_PAN]);
   207 	SEQ_START_NOTE(dev, v, note, vel);
   208 	voice[card][v].note = note;
   209 	voice[card][v].channel = chn;
   210 	voice[card][v].timestamp = ticks;
   211 	voice[card][v].dead = 0;
   212 	if ((c = channel[chn].controller[CTL_CHORUS_DEPTH] * 8)) {
   213 	    if (channel[chn].bender_range)
   214 		c /= channel[chn].bender_range;
   215 	    v = new_voice(dev, chn);
   216 	    SEQ_SET_PATCH(dev, v, channel[chn].program);
   217 	    SEQ_BENDER_RANGE(dev, v, (channel[chn].bender_range * 100));
   218 	    if (channel[chn].bender + c < 0x4000) {
   219 		SEQ_BENDER(dev, v, channel[chn].bender + c);
   220 	    } else {
   221 		SEQ_BENDER(dev, v, channel[chn].bender - c);
   222 	    }
   223 	    /* put chorus note on the "extreme" side */
   224 	    c = channel[chn].controller[CTL_PAN];
   225 	    if (c < 64)
   226 		c = 0;
   227 	    else if (c > 64)
   228 		c = 127;
   229 	    SEQ_CONTROL(dev, v, CTL_PAN, c);
   230 	    SEQ_START_NOTE(dev, v, note, vel);
   231 	    voice[card][v].note = note;
   232 	    voice[card][v].channel = chn;
   233 	    /* allow chorus note to be stolen very quickly */
   234 	    voice[card][v].timestamp = ticks / 2;
   235 	    voice[card][v].dead = 0;
   236 	}
   237     }
   238 }
   239 
   240 static int rpn1[16] =
   241 {127, 127, 127, 127, 127, 127, 127, 127,
   242  127, 127, 127, 127, 127, 127, 127, 127};
   243 static int rpn2[16] =
   244 {127, 127, 127, 127, 127, 127, 127, 127,
   245  127, 127, 127, 127, 127, 127, 127, 127};
   246 
   247 void seq_control(dev, chn, p1, p2)
   248 int dev, chn, p1, p2;
   249 {
   250     int i, card = CN;
   251 
   252     channel[chn].controller[p1] = p2;
   253 
   254     if (ISMIDI(chn)) {
   255 	SEQ_MIDIOUT(dev, MIDI_CTL_CHANGE + CHANNEL);
   256 	SEQ_MIDIOUT(dev, p1);
   257 	SEQ_MIDIOUT(dev, p2);
   258     }
   259     if (p1 == 7 || p1 == 39)
   260 	return;
   261     switch (p1) {
   262     case CTL_SUSTAIN:
   263 	if (ISAWE(chn)) {
   264 	    SEQ_CONTROL(dev, chn, p1, p2);
   265 	} else if (!ISMIDI(chn))
   266 	    if (p1 == CTL_SUSTAIN && !p2) {
   267 		for (i = 0; i < card_info[card].nr_voices; i++)
   268 		    if (voice[card][i].channel == chn
   269 			&& voice[card][i].dead) {
   270 			SEQ_STOP_NOTE(dev, i, voice[card][i].note, 64);
   271 			voice[card][i].dead = 0;
   272 		    }
   273 	    }
   274 	break;
   275     case CTL_REGIST_PARM_NUM_MSB:
   276 	rpn1[chn] = p2;
   277 	break;
   278     case CTL_REGIST_PARM_NUM_LSB:
   279 	rpn2[chn] = p2;
   280 	break;
   281     case CTL_DATA_ENTRY:
   282 	if (rpn1[chn] == 0 && rpn2[chn] == 0) {
   283 	    channel[chn].oldrange = channel[chn].bender_range;
   284 	    channel[chn].bender_range = p2;
   285 	    rpn1[chn] = rpn2[chn] = 127;
   286 	    if (ISAWE(chn)) {
   287 		SEQ_BENDER_RANGE(dev, chn, p2 * 100);
   288 	    } else if (!ISMIDI(chn))
   289 		for (i = 0; i < card_info[card].nr_voices; i++)
   290 		    SEQ_BENDER_RANGE(dev, i, p2 * 100);
   291 	}
   292 	break;
   293     default:
   294 	/* sent on the off chance the sound driver is enhanced */
   295 	if (ISAWE(chn)) {
   296 	    SEQ_CONTROL(dev, chn, p1, p2);
   297 	} else if (!ISMIDI(chn) && (p1 < 0x10 || (p1 & 0xf0) == 0x50))
   298 	    for (i = 0; i < card_info[card].nr_voices; i++)
   299 		if (voice[card][i].channel == chn)
   300 		    SEQ_CONTROL(dev, i, p1, p2);
   301 	break;
   302     }
   303 }
   304 
   305 void seq_chn_pressure(dev, chn, vel)
   306 int dev, chn, vel;
   307 {
   308     int card = CN, i;
   309 
   310     channel[chn].pressure = vel;
   311     if (ISMIDI(chn)) {
   312 	SEQ_MIDIOUT(dev, MIDI_CHN_PRESSURE + CHANNEL);
   313 	SEQ_MIDIOUT(dev, vel);
   314     } else if (ISAWE(chn)) {
   315 	AWE_CHN_PRESSURE(dev, chn, vel);
   316     } else
   317 	for (i = 0; i < card_info[dev].nr_voices; i++)
   318 	    if (voice[card][i].channel == chn)
   319 		SEQ_KEY_PRESSURE(dev, i, voice[card][i].note, vel);
   320 }
   321 
   322 void seq_bender(dev, chn, p1, p2)
   323 int dev, chn, p1, p2;
   324 {
   325     int card = CN, i, val;
   326 
   327     val = (p2 << 7) + p1;
   328     channel[chn].oldbend = channel[chn].bender;
   329     channel[chn].bender = val;
   330 
   331     if (ISMIDI(chn)) {
   332 	SEQ_MIDIOUT(dev, MIDI_PITCH_BEND + CHANNEL);
   333 	SEQ_MIDIOUT(dev, p1);
   334 	SEQ_MIDIOUT(dev, p2);
   335     } else if (ISAWE(chn)) {
   336 	SEQ_BENDER(dev, chn, val);
   337     } else
   338 	for (i = 0; i < card_info[dev].nr_voices; i++)
   339 	    if (voice[card][i].channel == chn)
   340 		SEQ_BENDER(dev, i, val);
   341 }
   342 
   343 void seq_reset()
   344 {
   345     int i, j;
   346 
   347     _seqbufptr = ticks = 0;
   348     ioctl(seqfd, SNDCTL_SEQ_RESET);
   349     for (i = 0; i < 16; i++) {
   350 	if (ISMIDI(i)) {
   351 	    seq_control(ext_dev,i,0,0);
   352 	    seq_control(ext_dev,i,32,0);
   353 	}
   354 	seq_set_patch(i, 0);
   355 	for (j = 0; j < 128; j++)
   356 	    note_vel[i][j] = 0;
   357 	channel[i].bender = channel[i].oldbend = 8192;
   358 	channel[i].bender_range = channel[i].oldrange = 2;
   359 	channel[i].controller[CTL_PAN] = 64;
   360 	channel[i].controller[CTL_SUSTAIN] = 0;
   361     }
   362     if (play_gus)
   363 	for (i = 0; i < card_info[gus_dev].nr_voices; i++) {
   364 	    SEQ_CONTROL(gus_dev, i, SEQ_VOLMODE, VOL_METHOD_LINEAR);
   365 	    if (voice[0][i].note)
   366 		SEQ_STOP_NOTE(gus_dev, i, voice[0][i].note, 64);
   367 	    voice[0][i].dead = voice[0][i].timestamp = -1;
   368 	}
   369     if (play_fm) {
   370 	if (wantopl3)
   371 	    ioctl(seqfd, SNDCTL_FM_4OP_ENABLE, &sb_dev);
   372 	for (i = 0; i < card_info[sb_dev].nr_voices; i++) {
   373 	    SEQ_CONTROL(sb_dev, i, SEQ_VOLMODE, VOL_METHOD_LINEAR);
   374 	    if (voice[1][i].note)
   375 		SEQ_STOP_NOTE(sb_dev, i, voice[1][i].note, 64);
   376 	    voice[1][i].dead = voice[1][i].timestamp = -1;
   377 	}
   378     }
   379     if (play_awe) {
   380 	AWE_SET_CHANNEL_MODE(awe_dev, 1);
   381 	AWE_DRUM_CHANNELS(awe_dev, perc);
   382 	AWE_TERMINATE_ALL(awe_dev);
   383 	for (i = 0; i < card_info[awe_dev].nr_voices; i++) {
   384 	    voice[0][i].dead = voice[0][i].timestamp = -1;
   385 	}
   386     }
   387     SEQ_DUMPBUF();
   388 }
   389 
   390 #endif /* linux || FreeBSD */