xref: /openbmc/linux/sound/drivers/opl3/opl3_midi.c (revision a6377d90)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  *  Copyright (c) by Uros Bizjak <uros@kss-loka.si>
4  *
5  *  Midi synth routines for OPL2/OPL3/OPL4 FM
6  */
7 
8 #undef DEBUG_ALLOC
9 #undef DEBUG_MIDI
10 
11 #include "opl3_voice.h"
12 #include <sound/asoundef.h>
13 
14 static void snd_opl3_note_off_unsafe(void *p, int note, int vel,
15 				     struct snd_midi_channel *chan);
16 /*
17  * The next table looks magical, but it certainly is not. Its values have
18  * been calculated as table[i]=8*log(i/64)/log(2) with an obvious exception
19  * for i=0. This log-table converts a linear volume-scaling (0..127) to a
20  * logarithmic scaling as present in the FM-synthesizer chips. so :    Volume
21  * 64 =  0 db = relative volume  0 and:    Volume 32 = -6 db = relative
22  * volume -8 it was implemented as a table because it is only 128 bytes and
23  * it saves a lot of log() calculations. (Rob Hooft <hooft@chem.ruu.nl>)
24  */
25 
26 static char opl3_volume_table[128] =
27 {
28 	-63, -48, -40, -35, -32, -29, -27, -26,
29 	-24, -23, -21, -20, -19, -18, -18, -17,
30 	-16, -15, -15, -14, -13, -13, -12, -12,
31 	-11, -11, -10, -10, -10, -9, -9, -8,
32 	-8, -8, -7, -7, -7, -6, -6, -6,
33 	-5, -5, -5, -5, -4, -4, -4, -4,
34 	-3, -3, -3, -3, -2, -2, -2, -2,
35 	-2, -1, -1, -1, -1, 0, 0, 0,
36 	0, 0, 0, 1, 1, 1, 1, 1,
37 	1, 2, 2, 2, 2, 2, 2, 2,
38 	3, 3, 3, 3, 3, 3, 3, 4,
39 	4, 4, 4, 4, 4, 4, 4, 5,
40 	5, 5, 5, 5, 5, 5, 5, 5,
41 	6, 6, 6, 6, 6, 6, 6, 6,
42 	6, 7, 7, 7, 7, 7, 7, 7,
43 	7, 7, 7, 8, 8, 8, 8, 8
44 };
45 
46 void snd_opl3_calc_volume(unsigned char *volbyte, int vel,
47 			  struct snd_midi_channel *chan)
48 {
49 	int oldvol, newvol, n;
50 	int volume;
51 
52 	volume = (vel * chan->gm_volume * chan->gm_expression) / (127*127);
53 	if (volume > 127)
54 		volume = 127;
55 
56 	oldvol = OPL3_TOTAL_LEVEL_MASK - (*volbyte & OPL3_TOTAL_LEVEL_MASK);
57 
58 	newvol = opl3_volume_table[volume] + oldvol;
59 	if (newvol > OPL3_TOTAL_LEVEL_MASK)
60 		newvol = OPL3_TOTAL_LEVEL_MASK;
61 	else if (newvol < 0)
62 		newvol = 0;
63 
64 	n = OPL3_TOTAL_LEVEL_MASK - (newvol & OPL3_TOTAL_LEVEL_MASK);
65 
66 	*volbyte = (*volbyte & OPL3_KSL_MASK) | (n & OPL3_TOTAL_LEVEL_MASK);
67 }
68 
69 /*
70  * Converts the note frequency to block and fnum values for the FM chip
71  */
72 static short opl3_note_table[16] =
73 {
74 	305, 323,	/* for pitch bending, -2 semitones */
75 	343, 363, 385, 408, 432, 458, 485, 514, 544, 577, 611, 647,
76 	686, 726	/* for pitch bending, +2 semitones */
77 };
78 
79 static void snd_opl3_calc_pitch(unsigned char *fnum, unsigned char *blocknum,
80 				int note, struct snd_midi_channel *chan)
81 {
82 	int block = ((note / 12) & 0x07) - 1;
83 	int idx = (note % 12) + 2;
84 	int freq;
85 
86 	if (chan->midi_pitchbend) {
87 		int pitchbend = chan->midi_pitchbend;
88 		int segment;
89 
90 		if (pitchbend < -0x2000)
91 			pitchbend = -0x2000;
92 		if (pitchbend > 0x1FFF)
93 			pitchbend = 0x1FFF;
94 
95 		segment = pitchbend / 0x1000;
96 		freq = opl3_note_table[idx+segment];
97 		freq += ((opl3_note_table[idx+segment+1] - freq) *
98 			 (pitchbend % 0x1000)) / 0x1000;
99 	} else {
100 		freq = opl3_note_table[idx];
101 	}
102 
103 	*fnum = (unsigned char) freq;
104 	*blocknum = ((freq >> 8) & OPL3_FNUM_HIGH_MASK) |
105 		((block << 2) & OPL3_BLOCKNUM_MASK);
106 }
107 
108 
109 #ifdef DEBUG_ALLOC
110 static void debug_alloc(struct snd_opl3 *opl3, char *s, int voice) {
111 	int i;
112 	char *str = "x.24";
113 
114 	printk(KERN_DEBUG "time %.5i: %s [%.2i]: ", opl3->use_time, s, voice);
115 	for (i = 0; i < opl3->max_voices; i++)
116 		printk(KERN_CONT "%c", *(str + opl3->voices[i].state + 1));
117 	printk(KERN_CONT "\n");
118 }
119 #endif
120 
121 /*
122  * Get a FM voice (channel) to play a note on.
123  */
124 static int opl3_get_voice(struct snd_opl3 *opl3, int instr_4op,
125 			  struct snd_midi_channel *chan) {
126 	int chan_4op_1;		/* first voice for 4op instrument */
127 	int chan_4op_2;		/* second voice for 4op instrument */
128 
129 	struct snd_opl3_voice *vp, *vp2;
130 	unsigned int voice_time;
131 	int i;
132 
133 #ifdef DEBUG_ALLOC
134 	char *alloc_type[3] = { "FREE     ", "CHEAP    ", "EXPENSIVE" };
135 #endif
136 
137 	/* This is our "allocation cost" table */
138 	enum {
139 		FREE = 0, CHEAP, EXPENSIVE, END
140 	};
141 
142 	/* Keeps track of what we are finding */
143 	struct best {
144 		unsigned int time;
145 		int voice;
146 	} best[END];
147 	struct best *bp;
148 
149 	for (i = 0; i < END; i++) {
150 		best[i].time = (unsigned int)(-1); /* XXX MAX_?INT really */
151 		best[i].voice = -1;
152 	}
153 
154 	/* Look through all the channels for the most suitable. */
155 	for (i = 0; i < opl3->max_voices; i++) {
156 		vp = &opl3->voices[i];
157 
158 		if (vp->state == SNDRV_OPL3_ST_NOT_AVAIL)
159 		  /* skip unavailable channels, allocated by
160 		     drum voices or by bounded 4op voices) */
161 			continue;
162 
163 		voice_time = vp->time;
164 		bp = best;
165 
166 		chan_4op_1 = ((i < 3) || (i > 8 && i < 12));
167 		chan_4op_2 = ((i > 2 && i < 6) || (i > 11 && i < 15));
168 		if (instr_4op) {
169 			/* allocate 4op voice */
170 			/* skip channels unavailable to 4op instrument */
171 			if (!chan_4op_1)
172 				continue;
173 
174 			if (vp->state)
175 				/* kill one voice, CHEAP */
176 				bp++;
177 			/* get state of bounded 2op channel
178 			   to be allocated for 4op instrument */
179 			vp2 = &opl3->voices[i + 3];
180 			if (vp2->state == SNDRV_OPL3_ST_ON_2OP) {
181 				/* kill two voices, EXPENSIVE */
182 				bp++;
183 				voice_time = (voice_time > vp->time) ?
184 					voice_time : vp->time;
185 			}
186 		} else {
187 			/* allocate 2op voice */
188 			if ((chan_4op_1) || (chan_4op_2))
189 				/* use bounded channels for 2op, CHEAP */
190 				bp++;
191 			else if (vp->state)
192 				/* kill one voice on 2op channel, CHEAP */
193 				bp++;
194 			/* raise kill cost to EXPENSIVE for all channels */
195 			if (vp->state)
196 				bp++;
197 		}
198 		if (voice_time < bp->time) {
199 			bp->time = voice_time;
200 			bp->voice = i;
201 		}
202 	}
203 
204 	for (i = 0; i < END; i++) {
205 		if (best[i].voice >= 0) {
206 #ifdef DEBUG_ALLOC
207 			printk(KERN_DEBUG "%s %iop allocation on voice %i\n",
208 			       alloc_type[i], instr_4op ? 4 : 2,
209 			       best[i].voice);
210 #endif
211 			return best[i].voice;
212 		}
213 	}
214 	/* not found */
215 	return -1;
216 }
217 
218 /* ------------------------------ */
219 
220 /*
221  * System timer interrupt function
222  */
223 void snd_opl3_timer_func(struct timer_list *t)
224 {
225 
226 	struct snd_opl3 *opl3 = from_timer(opl3, t, tlist);
227 	unsigned long flags;
228 	int again = 0;
229 	int i;
230 
231 	spin_lock_irqsave(&opl3->voice_lock, flags);
232 	for (i = 0; i < opl3->max_voices; i++) {
233 		struct snd_opl3_voice *vp = &opl3->voices[i];
234 		if (vp->state > 0 && vp->note_off_check) {
235 			if (vp->note_off == jiffies)
236 				snd_opl3_note_off_unsafe(opl3, vp->note, 0,
237 							 vp->chan);
238 			else
239 				again++;
240 		}
241 	}
242 	spin_unlock_irqrestore(&opl3->voice_lock, flags);
243 
244 	spin_lock_irqsave(&opl3->sys_timer_lock, flags);
245 	if (again)
246 		mod_timer(&opl3->tlist, jiffies + 1);	/* invoke again */
247 	else
248 		opl3->sys_timer_status = 0;
249 	spin_unlock_irqrestore(&opl3->sys_timer_lock, flags);
250 }
251 
252 /*
253  * Start system timer
254  */
255 static void snd_opl3_start_timer(struct snd_opl3 *opl3)
256 {
257 	unsigned long flags;
258 	spin_lock_irqsave(&opl3->sys_timer_lock, flags);
259 	if (! opl3->sys_timer_status) {
260 		mod_timer(&opl3->tlist, jiffies + 1);
261 		opl3->sys_timer_status = 1;
262 	}
263 	spin_unlock_irqrestore(&opl3->sys_timer_lock, flags);
264 }
265 
266 /* ------------------------------ */
267 
268 
269 static int snd_opl3_oss_map[MAX_OPL3_VOICES] = {
270 	0, 1, 2, 9, 10, 11, 6, 7, 8, 15, 16, 17, 3, 4 ,5, 12, 13, 14
271 };
272 
273 /*
274  * Start a note.
275  */
276 void snd_opl3_note_on(void *p, int note, int vel, struct snd_midi_channel *chan)
277 {
278 	struct snd_opl3 *opl3;
279 	int instr_4op;
280 
281 	int voice;
282 	struct snd_opl3_voice *vp, *vp2;
283 	unsigned short connect_mask;
284 	unsigned char connection;
285 	unsigned char vol_op[4];
286 
287 	int extra_prg = 0;
288 
289 	unsigned short reg_side;
290 	unsigned char op_offset;
291 	unsigned char voice_offset;
292 	unsigned short opl3_reg;
293 	unsigned char reg_val;
294 	unsigned char prg, bank;
295 
296 	int key = note;
297 	unsigned char fnum, blocknum;
298 	int i;
299 
300 	struct fm_patch *patch;
301 	struct fm_instrument *fm;
302 	unsigned long flags;
303 
304 	opl3 = p;
305 
306 #ifdef DEBUG_MIDI
307 	snd_printk(KERN_DEBUG "Note on, ch %i, inst %i, note %i, vel %i\n",
308 		   chan->number, chan->midi_program, note, vel);
309 #endif
310 
311 	/* in SYNTH mode, application takes care of voices */
312 	/* in SEQ mode, drum voice numbers are notes on drum channel */
313 	if (opl3->synth_mode == SNDRV_OPL3_MODE_SEQ) {
314 		if (chan->drum_channel) {
315 			/* percussion instruments are located in bank 128 */
316 			bank = 128;
317 			prg = note;
318 		} else {
319 			bank = chan->gm_bank_select;
320 			prg = chan->midi_program;
321 		}
322 	} else {
323 		/* Prepare for OSS mode */
324 		if (chan->number >= MAX_OPL3_VOICES)
325 			return;
326 
327 		/* OSS instruments are located in bank 127 */
328 		bank = 127;
329 		prg = chan->midi_program;
330 	}
331 
332 	spin_lock_irqsave(&opl3->voice_lock, flags);
333 
334 	if (use_internal_drums) {
335 		snd_opl3_drum_switch(opl3, note, vel, 1, chan);
336 		spin_unlock_irqrestore(&opl3->voice_lock, flags);
337 		return;
338 	}
339 
340  __extra_prg:
341 	patch = snd_opl3_find_patch(opl3, prg, bank, 0);
342 	if (!patch) {
343 		spin_unlock_irqrestore(&opl3->voice_lock, flags);
344 		return;
345 	}
346 
347 	fm = &patch->inst;
348 	switch (patch->type) {
349 	case FM_PATCH_OPL2:
350 		instr_4op = 0;
351 		break;
352 	case FM_PATCH_OPL3:
353 		if (opl3->hardware >= OPL3_HW_OPL3) {
354 			instr_4op = 1;
355 			break;
356 		}
357 		/* fall through */
358 	default:
359 		spin_unlock_irqrestore(&opl3->voice_lock, flags);
360 		return;
361 	}
362 #ifdef DEBUG_MIDI
363 	snd_printk(KERN_DEBUG "  --> OPL%i instrument: %s\n",
364 		   instr_4op ? 3 : 2, patch->name);
365 #endif
366 	/* in SYNTH mode, application takes care of voices */
367 	/* in SEQ mode, allocate voice on free OPL3 channel */
368 	if (opl3->synth_mode == SNDRV_OPL3_MODE_SEQ) {
369 		voice = opl3_get_voice(opl3, instr_4op, chan);
370 	} else {
371 		/* remap OSS voice */
372 		voice = snd_opl3_oss_map[chan->number];
373 	}
374 
375 	if (voice < 0) {
376 		spin_unlock_irqrestore(&opl3->voice_lock, flags);
377 		return;
378 	}
379 
380 	if (voice < MAX_OPL2_VOICES) {
381 		/* Left register block for voices 0 .. 8 */
382 		reg_side = OPL3_LEFT;
383 		voice_offset = voice;
384 		connect_mask = (OPL3_LEFT_4OP_0 << voice_offset) & 0x07;
385 	} else {
386 		/* Right register block for voices 9 .. 17 */
387 		reg_side = OPL3_RIGHT;
388 		voice_offset = voice - MAX_OPL2_VOICES;
389 		connect_mask = (OPL3_RIGHT_4OP_0 << voice_offset) & 0x38;
390 	}
391 
392 	/* kill voice on channel */
393 	vp = &opl3->voices[voice];
394 	if (vp->state > 0) {
395 		opl3_reg = reg_side | (OPL3_REG_KEYON_BLOCK + voice_offset);
396 		reg_val = vp->keyon_reg & ~OPL3_KEYON_BIT;
397 		opl3->command(opl3, opl3_reg, reg_val);
398 	}
399 	if (instr_4op) {
400 		vp2 = &opl3->voices[voice + 3];
401 		if (vp->state > 0) {
402 			opl3_reg = reg_side | (OPL3_REG_KEYON_BLOCK +
403 					       voice_offset + 3);
404 			reg_val = vp->keyon_reg & ~OPL3_KEYON_BIT;
405 			opl3->command(opl3, opl3_reg, reg_val);
406 		}
407 	}
408 
409 	/* set connection register */
410 	if (instr_4op) {
411 		if ((opl3->connection_reg ^ connect_mask) & connect_mask) {
412 			opl3->connection_reg |= connect_mask;
413 			/* set connection bit */
414 			opl3_reg = OPL3_RIGHT | OPL3_REG_CONNECTION_SELECT;
415 			opl3->command(opl3, opl3_reg, opl3->connection_reg);
416 		}
417 	} else {
418 		if ((opl3->connection_reg ^ ~connect_mask) & connect_mask) {
419 			opl3->connection_reg &= ~connect_mask;
420 			/* clear connection bit */
421 			opl3_reg = OPL3_RIGHT | OPL3_REG_CONNECTION_SELECT;
422 			opl3->command(opl3, opl3_reg, opl3->connection_reg);
423 		}
424 	}
425 
426 #ifdef DEBUG_MIDI
427 	snd_printk(KERN_DEBUG "  --> setting OPL3 connection: 0x%x\n",
428 		   opl3->connection_reg);
429 #endif
430 	/*
431 	 * calculate volume depending on connection
432 	 * between FM operators (see include/opl3.h)
433 	 */
434 	for (i = 0; i < (instr_4op ? 4 : 2); i++)
435 		vol_op[i] = fm->op[i].ksl_level;
436 
437 	connection = fm->feedback_connection[0] & 0x01;
438 	if (instr_4op) {
439 		connection <<= 1;
440 		connection |= fm->feedback_connection[1] & 0x01;
441 
442 		snd_opl3_calc_volume(&vol_op[3], vel, chan);
443 		switch (connection) {
444 		case 0x03:
445 			snd_opl3_calc_volume(&vol_op[2], vel, chan);
446 			/* fallthru */
447 		case 0x02:
448 			snd_opl3_calc_volume(&vol_op[0], vel, chan);
449 			break;
450 		case 0x01:
451 			snd_opl3_calc_volume(&vol_op[1], vel, chan);
452 		}
453 	} else {
454 		snd_opl3_calc_volume(&vol_op[1], vel, chan);
455 		if (connection)
456 			snd_opl3_calc_volume(&vol_op[0], vel, chan);
457 	}
458 
459 	/* Program the FM voice characteristics */
460 	for (i = 0; i < (instr_4op ? 4 : 2); i++) {
461 #ifdef DEBUG_MIDI
462 		snd_printk(KERN_DEBUG "  --> programming operator %i\n", i);
463 #endif
464 		op_offset = snd_opl3_regmap[voice_offset][i];
465 
466 		/* Set OPL3 AM_VIB register of requested voice/operator */
467 		reg_val = fm->op[i].am_vib;
468 		opl3_reg = reg_side | (OPL3_REG_AM_VIB + op_offset);
469 		opl3->command(opl3, opl3_reg, reg_val);
470 
471 		/* Set OPL3 KSL_LEVEL register of requested voice/operator */
472 		reg_val = vol_op[i];
473 		opl3_reg = reg_side | (OPL3_REG_KSL_LEVEL + op_offset);
474 		opl3->command(opl3, opl3_reg, reg_val);
475 
476 		/* Set OPL3 ATTACK_DECAY register of requested voice/operator */
477 		reg_val = fm->op[i].attack_decay;
478 		opl3_reg = reg_side | (OPL3_REG_ATTACK_DECAY + op_offset);
479 		opl3->command(opl3, opl3_reg, reg_val);
480 
481 		/* Set OPL3 SUSTAIN_RELEASE register of requested voice/operator */
482 		reg_val = fm->op[i].sustain_release;
483 		opl3_reg = reg_side | (OPL3_REG_SUSTAIN_RELEASE + op_offset);
484 		opl3->command(opl3, opl3_reg, reg_val);
485 
486 		/* Select waveform */
487 		reg_val = fm->op[i].wave_select;
488 		opl3_reg = reg_side | (OPL3_REG_WAVE_SELECT + op_offset);
489 		opl3->command(opl3, opl3_reg, reg_val);
490 	}
491 
492 	/* Set operator feedback and 2op inter-operator connection */
493 	reg_val = fm->feedback_connection[0];
494 	/* Set output voice connection */
495 	reg_val |= OPL3_STEREO_BITS;
496 	if (chan->gm_pan < 43)
497 		reg_val &= ~OPL3_VOICE_TO_RIGHT;
498 	if (chan->gm_pan > 85)
499 		reg_val &= ~OPL3_VOICE_TO_LEFT;
500 	opl3_reg = reg_side | (OPL3_REG_FEEDBACK_CONNECTION + voice_offset);
501 	opl3->command(opl3, opl3_reg, reg_val);
502 
503 	if (instr_4op) {
504 		/* Set 4op inter-operator connection */
505 		reg_val = fm->feedback_connection[1] & OPL3_CONNECTION_BIT;
506 		/* Set output voice connection */
507 		reg_val |= OPL3_STEREO_BITS;
508 		if (chan->gm_pan < 43)
509 			reg_val &= ~OPL3_VOICE_TO_RIGHT;
510 		if (chan->gm_pan > 85)
511 			reg_val &= ~OPL3_VOICE_TO_LEFT;
512 		opl3_reg = reg_side | (OPL3_REG_FEEDBACK_CONNECTION +
513 				       voice_offset + 3);
514 		opl3->command(opl3, opl3_reg, reg_val);
515 	}
516 
517 	/*
518 	 * Special treatment of percussion notes for fm:
519 	 * Requested pitch is really program, and pitch for
520 	 * device is whatever was specified in the patch library.
521 	 */
522 	if (fm->fix_key)
523 		note = fm->fix_key;
524 	/*
525 	 * use transpose if defined in patch library
526 	 */
527 	if (fm->trnsps)
528 		note += (fm->trnsps - 64);
529 
530 	snd_opl3_calc_pitch(&fnum, &blocknum, note, chan);
531 
532 	/* Set OPL3 FNUM_LOW register of requested voice */
533 	opl3_reg = reg_side | (OPL3_REG_FNUM_LOW + voice_offset);
534 	opl3->command(opl3, opl3_reg, fnum);
535 
536 	opl3->voices[voice].keyon_reg = blocknum;
537 
538 	/* Set output sound flag */
539 	blocknum |= OPL3_KEYON_BIT;
540 
541 #ifdef DEBUG_MIDI
542 	snd_printk(KERN_DEBUG "  --> trigger voice %i\n", voice);
543 #endif
544 	/* Set OPL3 KEYON_BLOCK register of requested voice */
545 	opl3_reg = reg_side | (OPL3_REG_KEYON_BLOCK + voice_offset);
546 	opl3->command(opl3, opl3_reg, blocknum);
547 
548 	/* kill note after fixed duration (in centiseconds) */
549 	if (fm->fix_dur) {
550 		opl3->voices[voice].note_off = jiffies +
551 			(fm->fix_dur * HZ) / 100;
552 		snd_opl3_start_timer(opl3);
553 		opl3->voices[voice].note_off_check = 1;
554 	} else
555 		opl3->voices[voice].note_off_check = 0;
556 
557 	/* get extra pgm, but avoid possible loops */
558 	extra_prg = (extra_prg) ? 0 : fm->modes;
559 
560 	/* do the bookkeeping */
561 	vp->time = opl3->use_time++;
562 	vp->note = key;
563 	vp->chan = chan;
564 
565 	if (instr_4op) {
566 		vp->state = SNDRV_OPL3_ST_ON_4OP;
567 
568 		vp2 = &opl3->voices[voice + 3];
569 		vp2->time = opl3->use_time++;
570 		vp2->note = key;
571 		vp2->chan = chan;
572 		vp2->state = SNDRV_OPL3_ST_NOT_AVAIL;
573 	} else {
574 		if (vp->state == SNDRV_OPL3_ST_ON_4OP) {
575 			/* 4op killed by 2op, release bounded voice */
576 			vp2 = &opl3->voices[voice + 3];
577 			vp2->time = opl3->use_time++;
578 			vp2->state = SNDRV_OPL3_ST_OFF;
579 		}
580 		vp->state = SNDRV_OPL3_ST_ON_2OP;
581 	}
582 
583 #ifdef DEBUG_ALLOC
584 	debug_alloc(opl3, "note on ", voice);
585 #endif
586 
587 	/* allocate extra program if specified in patch library */
588 	if (extra_prg) {
589 		if (extra_prg > 128) {
590 			bank = 128;
591 			/* percussions start at 35 */
592 			prg = extra_prg - 128 + 35 - 1;
593 		} else {
594 			bank = 0;
595 			prg = extra_prg - 1;
596 		}
597 #ifdef DEBUG_MIDI
598 		snd_printk(KERN_DEBUG " *** allocating extra program\n");
599 #endif
600 		goto __extra_prg;
601 	}
602 	spin_unlock_irqrestore(&opl3->voice_lock, flags);
603 }
604 
605 static void snd_opl3_kill_voice(struct snd_opl3 *opl3, int voice)
606 {
607 	unsigned short reg_side;
608 	unsigned char voice_offset;
609 	unsigned short opl3_reg;
610 
611 	struct snd_opl3_voice *vp, *vp2;
612 
613 	if (snd_BUG_ON(voice >= MAX_OPL3_VOICES))
614 		return;
615 
616 	vp = &opl3->voices[voice];
617 	if (voice < MAX_OPL2_VOICES) {
618 		/* Left register block for voices 0 .. 8 */
619 		reg_side = OPL3_LEFT;
620 		voice_offset = voice;
621 	} else {
622 		/* Right register block for voices 9 .. 17 */
623 		reg_side = OPL3_RIGHT;
624 		voice_offset = voice - MAX_OPL2_VOICES;
625 	}
626 
627 	/* kill voice */
628 #ifdef DEBUG_MIDI
629 	snd_printk(KERN_DEBUG "  --> kill voice %i\n", voice);
630 #endif
631 	opl3_reg = reg_side | (OPL3_REG_KEYON_BLOCK + voice_offset);
632 	/* clear Key ON bit */
633 	opl3->command(opl3, opl3_reg, vp->keyon_reg);
634 
635 	/* do the bookkeeping */
636 	vp->time = opl3->use_time++;
637 
638 	if (vp->state == SNDRV_OPL3_ST_ON_4OP) {
639 		vp2 = &opl3->voices[voice + 3];
640 
641 		vp2->time = opl3->use_time++;
642 		vp2->state = SNDRV_OPL3_ST_OFF;
643 	}
644 	vp->state = SNDRV_OPL3_ST_OFF;
645 #ifdef DEBUG_ALLOC
646 	debug_alloc(opl3, "note off", voice);
647 #endif
648 
649 }
650 
651 /*
652  * Release a note in response to a midi note off.
653  */
654 static void snd_opl3_note_off_unsafe(void *p, int note, int vel,
655 				     struct snd_midi_channel *chan)
656 {
657   	struct snd_opl3 *opl3;
658 
659 	int voice;
660 	struct snd_opl3_voice *vp;
661 
662 	opl3 = p;
663 
664 #ifdef DEBUG_MIDI
665 	snd_printk(KERN_DEBUG "Note off, ch %i, inst %i, note %i\n",
666 		   chan->number, chan->midi_program, note);
667 #endif
668 
669 	if (opl3->synth_mode == SNDRV_OPL3_MODE_SEQ) {
670 		if (chan->drum_channel && use_internal_drums) {
671 			snd_opl3_drum_switch(opl3, note, vel, 0, chan);
672 			return;
673 		}
674 		/* this loop will hopefully kill all extra voices, because
675 		   they are grouped by the same channel and note values */
676 		for (voice = 0; voice < opl3->max_voices; voice++) {
677 			vp = &opl3->voices[voice];
678 			if (vp->state > 0 && vp->chan == chan && vp->note == note) {
679 				snd_opl3_kill_voice(opl3, voice);
680 			}
681 		}
682 	} else {
683 		/* remap OSS voices */
684 		if (chan->number < MAX_OPL3_VOICES) {
685 			voice = snd_opl3_oss_map[chan->number];
686 			snd_opl3_kill_voice(opl3, voice);
687 		}
688 	}
689 }
690 
691 void snd_opl3_note_off(void *p, int note, int vel,
692 		       struct snd_midi_channel *chan)
693 {
694 	struct snd_opl3 *opl3 = p;
695 	unsigned long flags;
696 
697 	spin_lock_irqsave(&opl3->voice_lock, flags);
698 	snd_opl3_note_off_unsafe(p, note, vel, chan);
699 	spin_unlock_irqrestore(&opl3->voice_lock, flags);
700 }
701 
702 /*
703  * key pressure change
704  */
705 void snd_opl3_key_press(void *p, int note, int vel, struct snd_midi_channel *chan)
706 {
707 #ifdef DEBUG_MIDI
708 	snd_printk(KERN_DEBUG "Key pressure, ch#: %i, inst#: %i\n",
709 		   chan->number, chan->midi_program);
710 #endif
711 }
712 
713 /*
714  * terminate note
715  */
716 void snd_opl3_terminate_note(void *p, int note, struct snd_midi_channel *chan)
717 {
718 #ifdef DEBUG_MIDI
719 	snd_printk(KERN_DEBUG "Terminate note, ch#: %i, inst#: %i\n",
720 		   chan->number, chan->midi_program);
721 #endif
722 }
723 
724 static void snd_opl3_update_pitch(struct snd_opl3 *opl3, int voice)
725 {
726 	unsigned short reg_side;
727 	unsigned char voice_offset;
728 	unsigned short opl3_reg;
729 
730 	unsigned char fnum, blocknum;
731 
732 	struct snd_opl3_voice *vp;
733 
734 	if (snd_BUG_ON(voice >= MAX_OPL3_VOICES))
735 		return;
736 
737 	vp = &opl3->voices[voice];
738 	if (vp->chan == NULL)
739 		return; /* not allocated? */
740 
741 	if (voice < MAX_OPL2_VOICES) {
742 		/* Left register block for voices 0 .. 8 */
743 		reg_side = OPL3_LEFT;
744 		voice_offset = voice;
745 	} else {
746 		/* Right register block for voices 9 .. 17 */
747 		reg_side = OPL3_RIGHT;
748 		voice_offset = voice - MAX_OPL2_VOICES;
749 	}
750 
751 	snd_opl3_calc_pitch(&fnum, &blocknum, vp->note, vp->chan);
752 
753 	/* Set OPL3 FNUM_LOW register of requested voice */
754 	opl3_reg = reg_side | (OPL3_REG_FNUM_LOW + voice_offset);
755 	opl3->command(opl3, opl3_reg, fnum);
756 
757 	vp->keyon_reg = blocknum;
758 
759 	/* Set output sound flag */
760 	blocknum |= OPL3_KEYON_BIT;
761 
762 	/* Set OPL3 KEYON_BLOCK register of requested voice */
763 	opl3_reg = reg_side | (OPL3_REG_KEYON_BLOCK + voice_offset);
764 	opl3->command(opl3, opl3_reg, blocknum);
765 
766 	vp->time = opl3->use_time++;
767 }
768 
769 /*
770  * Update voice pitch controller
771  */
772 static void snd_opl3_pitch_ctrl(struct snd_opl3 *opl3, struct snd_midi_channel *chan)
773 {
774 	int voice;
775 	struct snd_opl3_voice *vp;
776 
777 	unsigned long flags;
778 
779 	spin_lock_irqsave(&opl3->voice_lock, flags);
780 
781 	if (opl3->synth_mode == SNDRV_OPL3_MODE_SEQ) {
782 		for (voice = 0; voice < opl3->max_voices; voice++) {
783 			vp = &opl3->voices[voice];
784 			if (vp->state > 0 && vp->chan == chan) {
785 				snd_opl3_update_pitch(opl3, voice);
786 			}
787 		}
788 	} else {
789 		/* remap OSS voices */
790 		if (chan->number < MAX_OPL3_VOICES) {
791 			voice = snd_opl3_oss_map[chan->number];
792 			snd_opl3_update_pitch(opl3, voice);
793 		}
794 	}
795 	spin_unlock_irqrestore(&opl3->voice_lock, flags);
796 }
797 
798 /*
799  * Deal with a controller type event.  This includes all types of
800  * control events, not just the midi controllers
801  */
802 void snd_opl3_control(void *p, int type, struct snd_midi_channel *chan)
803 {
804   	struct snd_opl3 *opl3;
805 
806 	opl3 = p;
807 #ifdef DEBUG_MIDI
808 	snd_printk(KERN_DEBUG "Controller, TYPE = %i, ch#: %i, inst#: %i\n",
809 		   type, chan->number, chan->midi_program);
810 #endif
811 
812 	switch (type) {
813 	case MIDI_CTL_MSB_MODWHEEL:
814 		if (chan->control[MIDI_CTL_MSB_MODWHEEL] > 63)
815 			opl3->drum_reg |= OPL3_VIBRATO_DEPTH;
816 		else
817 			opl3->drum_reg &= ~OPL3_VIBRATO_DEPTH;
818 		opl3->command(opl3, OPL3_LEFT | OPL3_REG_PERCUSSION,
819 				 opl3->drum_reg);
820 		break;
821 	case MIDI_CTL_E2_TREMOLO_DEPTH:
822 		if (chan->control[MIDI_CTL_E2_TREMOLO_DEPTH] > 63)
823 			opl3->drum_reg |= OPL3_TREMOLO_DEPTH;
824 		else
825 			opl3->drum_reg &= ~OPL3_TREMOLO_DEPTH;
826 		opl3->command(opl3, OPL3_LEFT | OPL3_REG_PERCUSSION,
827 				 opl3->drum_reg);
828 		break;
829 	case MIDI_CTL_PITCHBEND:
830 		snd_opl3_pitch_ctrl(opl3, chan);
831 		break;
832 	}
833 }
834 
835 /*
836  * NRPN events
837  */
838 void snd_opl3_nrpn(void *p, struct snd_midi_channel *chan,
839 		   struct snd_midi_channel_set *chset)
840 {
841 #ifdef DEBUG_MIDI
842 	snd_printk(KERN_DEBUG "NRPN, ch#: %i, inst#: %i\n",
843 		   chan->number, chan->midi_program);
844 #endif
845 }
846 
847 /*
848  * receive sysex
849  */
850 void snd_opl3_sysex(void *p, unsigned char *buf, int len,
851 		    int parsed, struct snd_midi_channel_set *chset)
852 {
853 #ifdef DEBUG_MIDI
854 	snd_printk(KERN_DEBUG "SYSEX\n");
855 #endif
856 }
857