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