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