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