/home/lenb/src/to-linus branch 'acpi-2.6.12'
[linux-2.6] / sound / core / seq / seq_midi_emul.c
1 /*
2  *  GM/GS/XG midi module.
3  *
4  *  Copyright (C) 1999 Steve Ratcliffe
5  *
6  *  Based on awe_wave.c by Takashi Iwai
7  *
8  *   This program is free software; you can redistribute it and/or modify
9  *   it under the terms of the GNU General Public License as published by
10  *   the Free Software Foundation; either version 2 of the License, or
11  *   (at your option) any later version.
12  *
13  *   This program is distributed in the hope that it will be useful,
14  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *   GNU General Public License for more details.
17  *
18  *   You should have received a copy of the GNU General Public License
19  *   along with this program; if not, write to the Free Software
20  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
21  *
22  */
23 /*
24  * This module is used to keep track of the current midi state.
25  * It can be used for drivers that are required to emulate midi when
26  * the hardware doesn't.
27  *
28  * It was written for a AWE64 driver, but there should be no AWE specific
29  * code in here.  If there is it should be reported as a bug.
30  */
31
32 #include <sound/driver.h>
33 #include <linux/init.h>
34 #include <linux/slab.h>
35 #include <linux/string.h>
36 #include <sound/core.h>
37 #include <sound/seq_kernel.h>
38 #include <sound/seq_midi_emul.h>
39 #include <sound/initval.h>
40 #include <sound/asoundef.h>
41
42 MODULE_AUTHOR("Takashi Iwai / Steve Ratcliffe");
43 MODULE_DESCRIPTION("Advanced Linux Sound Architecture sequencer MIDI emulation.");
44 MODULE_LICENSE("GPL");
45
46 /* Prototypes for static functions */
47 static void note_off(snd_midi_op_t *ops, void *drv, snd_midi_channel_t *chan, int note, int vel);
48 static void do_control(snd_midi_op_t *ops, void *private,
49                        snd_midi_channel_set_t *chset, snd_midi_channel_t *chan,
50                        int control, int value);
51 static void rpn(snd_midi_op_t *ops, void *drv, snd_midi_channel_t *chan, snd_midi_channel_set_t *chset);
52 static void nrpn(snd_midi_op_t *ops, void *drv, snd_midi_channel_t *chan, snd_midi_channel_set_t *chset);
53 static void sysex(snd_midi_op_t *ops, void *private, unsigned char *sysex, int len, snd_midi_channel_set_t *chset);
54 static void all_sounds_off(snd_midi_op_t *ops, void *private, snd_midi_channel_t *chan);
55 static void all_notes_off(snd_midi_op_t *ops, void *private, snd_midi_channel_t *chan);
56 static void snd_midi_reset_controllers(snd_midi_channel_t *chan);
57 static void reset_all_channels(snd_midi_channel_set_t *chset);
58
59
60 /*
61  * Process an event in a driver independent way.  This means dealing
62  * with RPN, NRPN, SysEx etc that are defined for common midi applications
63  * such as GM, GS and XG.
64  * There modes that this module will run in are:
65  *   Generic MIDI - no interpretation at all, it will just save current values
66  *                  of controlers etc.
67  *   GM - You can use all gm_ prefixed elements of chan.  Controls, RPN, NRPN,
68  *        SysEx will be interpreded as defined in General Midi.
69  *   GS - You can use all gs_ prefixed elements of chan. Codes for GS will be
70  *        interpreted.
71  *   XG - You can use all xg_ prefixed elements of chan.  Codes for XG will
72  *        be interpreted.
73  */
74 void
75 snd_midi_process_event(snd_midi_op_t *ops,
76                        snd_seq_event_t *ev, snd_midi_channel_set_t *chanset)
77 {
78         snd_midi_channel_t *chan;
79         void *drv;
80         int dest_channel = 0;
81
82         if (ev == NULL || chanset == NULL) {
83                 snd_printd("ev or chanbase NULL (snd_midi_process_event)\n");
84                 return;
85         }
86         if (chanset->channels == NULL)
87                 return;
88
89         if (snd_seq_ev_is_channel_type(ev)) {
90                 dest_channel = ev->data.note.channel;
91                 if (dest_channel >= chanset->max_channels) {
92                         snd_printd("dest channel is %d, max is %d\n", dest_channel, chanset->max_channels);
93                         return;
94                 }
95         }
96
97         chan = chanset->channels + dest_channel;
98         drv  = chanset->private_data;
99
100         /* EVENT_NOTE should be processed before queued */
101         if (ev->type == SNDRV_SEQ_EVENT_NOTE)
102                 return;
103
104         /* Make sure that we don't have a note on that should really be
105          * a note off */
106         if (ev->type == SNDRV_SEQ_EVENT_NOTEON && ev->data.note.velocity == 0)
107                 ev->type = SNDRV_SEQ_EVENT_NOTEOFF;
108
109         /* Make sure the note is within array range */
110         if (ev->type == SNDRV_SEQ_EVENT_NOTEON ||
111             ev->type == SNDRV_SEQ_EVENT_NOTEOFF ||
112             ev->type == SNDRV_SEQ_EVENT_KEYPRESS) {
113                 if (ev->data.note.note >= 128)
114                         return;
115         }
116
117         switch (ev->type) {
118         case SNDRV_SEQ_EVENT_NOTEON:
119                 if (chan->note[ev->data.note.note] & SNDRV_MIDI_NOTE_ON) {
120                         if (ops->note_off)
121                                 ops->note_off(drv, ev->data.note.note, 0, chan);
122                 }
123                 chan->note[ev->data.note.note] = SNDRV_MIDI_NOTE_ON;
124                 if (ops->note_on)
125                         ops->note_on(drv, ev->data.note.note, ev->data.note.velocity, chan);
126                 break;
127         case SNDRV_SEQ_EVENT_NOTEOFF:
128                 if (! (chan->note[ev->data.note.note] & SNDRV_MIDI_NOTE_ON))
129                         break;
130                 if (ops->note_off)
131                         note_off(ops, drv, chan, ev->data.note.note, ev->data.note.velocity);
132                 break;
133         case SNDRV_SEQ_EVENT_KEYPRESS:
134                 if (ops->key_press)
135                         ops->key_press(drv, ev->data.note.note, ev->data.note.velocity, chan);
136                 break;
137         case SNDRV_SEQ_EVENT_CONTROLLER:
138                 do_control(ops, drv, chanset, chan,
139                            ev->data.control.param, ev->data.control.value);
140                 break;
141         case SNDRV_SEQ_EVENT_PGMCHANGE:
142                 chan->midi_program = ev->data.control.value;
143                 break;
144         case SNDRV_SEQ_EVENT_PITCHBEND:
145                 chan->midi_pitchbend = ev->data.control.value;
146                 if (ops->control)
147                         ops->control(drv, MIDI_CTL_PITCHBEND, chan);
148                 break;
149         case SNDRV_SEQ_EVENT_CHANPRESS:
150                 chan->midi_pressure = ev->data.control.value;
151                 if (ops->control)
152                         ops->control(drv, MIDI_CTL_CHAN_PRESSURE, chan);
153                 break;
154         case SNDRV_SEQ_EVENT_CONTROL14:
155                 /* Best guess is that this is any of the 14 bit controller values */
156                 if (ev->data.control.param < 32) {
157                         /* set low part first */
158                         chan->control[ev->data.control.param + 32] =
159                                 ev->data.control.value & 0x7f;
160                         do_control(ops, drv, chanset, chan,
161                                    ev->data.control.param,
162                                    ((ev->data.control.value>>7) & 0x7f));
163                 } else
164                         do_control(ops, drv, chanset, chan,
165                                    ev->data.control.param,
166                                    ev->data.control.value);
167                 break;
168         case SNDRV_SEQ_EVENT_NONREGPARAM:
169                 /* Break it back into its controler values */
170                 chan->param_type = SNDRV_MIDI_PARAM_TYPE_NONREGISTERED;
171                 chan->control[MIDI_CTL_MSB_DATA_ENTRY]
172                         = (ev->data.control.value >> 7) & 0x7f;
173                 chan->control[MIDI_CTL_LSB_DATA_ENTRY]
174                         = ev->data.control.value & 0x7f;
175                 chan->control[MIDI_CTL_NONREG_PARM_NUM_MSB]
176                         = (ev->data.control.param >> 7) & 0x7f;
177                 chan->control[MIDI_CTL_NONREG_PARM_NUM_LSB]
178                         = ev->data.control.param & 0x7f;
179                 nrpn(ops, drv, chan, chanset);
180                 break;
181         case SNDRV_SEQ_EVENT_REGPARAM:
182                 /* Break it back into its controler values */
183                 chan->param_type = SNDRV_MIDI_PARAM_TYPE_REGISTERED;
184                 chan->control[MIDI_CTL_MSB_DATA_ENTRY]
185                         = (ev->data.control.value >> 7) & 0x7f;
186                 chan->control[MIDI_CTL_LSB_DATA_ENTRY]
187                         = ev->data.control.value & 0x7f;
188                 chan->control[MIDI_CTL_REGIST_PARM_NUM_MSB]
189                         = (ev->data.control.param >> 7) & 0x7f;
190                 chan->control[MIDI_CTL_REGIST_PARM_NUM_LSB]
191                         = ev->data.control.param & 0x7f;
192                 rpn(ops, drv, chan, chanset);
193                 break;
194         case SNDRV_SEQ_EVENT_SYSEX:
195                 if ((ev->flags & SNDRV_SEQ_EVENT_LENGTH_MASK) == SNDRV_SEQ_EVENT_LENGTH_VARIABLE) {
196                         unsigned char sysexbuf[64];
197                         int len;
198                         len = snd_seq_expand_var_event(ev, sizeof(sysexbuf), sysexbuf, 1, 0);
199                         if (len > 0)
200                                 sysex(ops, drv, sysexbuf, len, chanset);
201                 }
202                 break;
203         case SNDRV_SEQ_EVENT_SONGPOS:
204         case SNDRV_SEQ_EVENT_SONGSEL:
205         case SNDRV_SEQ_EVENT_CLOCK:
206         case SNDRV_SEQ_EVENT_START:
207         case SNDRV_SEQ_EVENT_CONTINUE:
208         case SNDRV_SEQ_EVENT_STOP:
209         case SNDRV_SEQ_EVENT_QFRAME:
210         case SNDRV_SEQ_EVENT_TEMPO:
211         case SNDRV_SEQ_EVENT_TIMESIGN:
212         case SNDRV_SEQ_EVENT_KEYSIGN:
213                 goto not_yet;
214         case SNDRV_SEQ_EVENT_SENSING:
215                 break;
216         case SNDRV_SEQ_EVENT_CLIENT_START:
217         case SNDRV_SEQ_EVENT_CLIENT_EXIT:
218         case SNDRV_SEQ_EVENT_CLIENT_CHANGE:
219         case SNDRV_SEQ_EVENT_PORT_START:
220         case SNDRV_SEQ_EVENT_PORT_EXIT:
221         case SNDRV_SEQ_EVENT_PORT_CHANGE:
222         case SNDRV_SEQ_EVENT_SAMPLE:
223         case SNDRV_SEQ_EVENT_SAMPLE_START:
224         case SNDRV_SEQ_EVENT_SAMPLE_STOP:
225         case SNDRV_SEQ_EVENT_SAMPLE_FREQ:
226         case SNDRV_SEQ_EVENT_SAMPLE_VOLUME:
227         case SNDRV_SEQ_EVENT_SAMPLE_LOOP:
228         case SNDRV_SEQ_EVENT_SAMPLE_POSITION:
229         case SNDRV_SEQ_EVENT_ECHO:
230         not_yet:
231         default:
232                 /*snd_printd("Unimplemented event %d\n", ev->type);*/
233                 break;
234         }
235 }
236
237
238 /*
239  * release note
240  */
241 static void
242 note_off(snd_midi_op_t *ops, void *drv, snd_midi_channel_t *chan, int note, int vel)
243 {
244         if (chan->gm_hold) {
245                 /* Hold this note until pedal is turned off */
246                 chan->note[note] |= SNDRV_MIDI_NOTE_RELEASED;
247         } else if (chan->note[note] & SNDRV_MIDI_NOTE_SOSTENUTO) {
248                 /* Mark this note as release; it will be turned off when sostenuto
249                  * is turned off */
250                 chan->note[note] |= SNDRV_MIDI_NOTE_RELEASED;
251         } else {
252                 chan->note[note] = 0;
253                 if (ops->note_off)
254                         ops->note_off(drv, note, vel, chan);
255         }
256 }
257
258 /*
259  * Do all driver independent operations for this controler and pass
260  * events that need to take place immediately to the driver.
261  */
262 static void
263 do_control(snd_midi_op_t *ops, void *drv, snd_midi_channel_set_t *chset,
264            snd_midi_channel_t *chan, int control, int value)
265 {
266         int  i;
267
268         /* Switches */
269         if ((control >=64 && control <=69) || (control >= 80 && control <= 83)) {
270                 /* These are all switches; either off or on so set to 0 or 127 */
271                 value = (value >= 64)? 127: 0;
272         }
273         chan->control[control] = value;
274
275         switch (control) {
276         case MIDI_CTL_SUSTAIN:
277                 if (value == 0) {
278                         /* Sustain has been released, turn off held notes */
279                         for (i = 0; i < 128; i++) {
280                                 if (chan->note[i] & SNDRV_MIDI_NOTE_RELEASED) {
281                                         chan->note[i] = SNDRV_MIDI_NOTE_OFF;
282                                         if (ops->note_off)
283                                                 ops->note_off(drv, i, 0, chan);
284                                 }
285                         }
286                 }
287                 break;
288         case MIDI_CTL_PORTAMENTO:
289                 break;
290         case MIDI_CTL_SOSTENUTO:
291                 if (value) {
292                         /* Mark each note that is currently held down */
293                         for (i = 0; i < 128; i++) {
294                                 if (chan->note[i] & SNDRV_MIDI_NOTE_ON)
295                                         chan->note[i] |= SNDRV_MIDI_NOTE_SOSTENUTO;
296                         }
297                 } else {
298                         /* release all notes that were held */
299                         for (i = 0; i < 128; i++) {
300                                 if (chan->note[i] & SNDRV_MIDI_NOTE_SOSTENUTO) {
301                                         chan->note[i] &= ~SNDRV_MIDI_NOTE_SOSTENUTO;
302                                         if (chan->note[i] & SNDRV_MIDI_NOTE_RELEASED) {
303                                                 chan->note[i] = SNDRV_MIDI_NOTE_OFF;
304                                                 if (ops->note_off)
305                                                         ops->note_off(drv, i, 0, chan);
306                                         }
307                                 }
308                         }
309                 }
310                 break;
311         case MIDI_CTL_MSB_DATA_ENTRY:
312                 chan->control[MIDI_CTL_LSB_DATA_ENTRY] = 0;
313                 /* go through here */
314         case MIDI_CTL_LSB_DATA_ENTRY:
315                 if (chan->param_type == SNDRV_MIDI_PARAM_TYPE_REGISTERED)
316                         rpn(ops, drv, chan, chset);
317                 else
318                         nrpn(ops, drv, chan, chset);
319                 break;
320         case MIDI_CTL_REGIST_PARM_NUM_LSB:
321         case MIDI_CTL_REGIST_PARM_NUM_MSB:
322                 chan->param_type = SNDRV_MIDI_PARAM_TYPE_REGISTERED;
323                 break;
324         case MIDI_CTL_NONREG_PARM_NUM_LSB:
325         case MIDI_CTL_NONREG_PARM_NUM_MSB:
326                 chan->param_type = SNDRV_MIDI_PARAM_TYPE_NONREGISTERED;
327                 break;
328
329         case MIDI_CTL_ALL_SOUNDS_OFF:
330                 all_sounds_off(ops, drv, chan);
331                 break;
332
333         case MIDI_CTL_ALL_NOTES_OFF:
334                 all_notes_off(ops, drv, chan);
335                 break;
336
337         case MIDI_CTL_MSB_BANK:
338                 if (chset->midi_mode == SNDRV_MIDI_MODE_XG) {
339                         if (value == 127)
340                                 chan->drum_channel = 1;
341                         else
342                                 chan->drum_channel = 0;
343                 }
344                 break;
345         case MIDI_CTL_LSB_BANK:
346                 break;
347
348         case MIDI_CTL_RESET_CONTROLLERS:
349                 snd_midi_reset_controllers(chan);
350                 break;
351
352         case MIDI_CTL_SOFT_PEDAL:
353         case MIDI_CTL_LEGATO_FOOTSWITCH:
354         case MIDI_CTL_HOLD2:
355         case MIDI_CTL_SC1_SOUND_VARIATION:
356         case MIDI_CTL_SC2_TIMBRE:
357         case MIDI_CTL_SC3_RELEASE_TIME:
358         case MIDI_CTL_SC4_ATTACK_TIME:
359         case MIDI_CTL_SC5_BRIGHTNESS:
360         case MIDI_CTL_E1_REVERB_DEPTH:
361         case MIDI_CTL_E2_TREMOLO_DEPTH:
362         case MIDI_CTL_E3_CHORUS_DEPTH:
363         case MIDI_CTL_E4_DETUNE_DEPTH:
364         case MIDI_CTL_E5_PHASER_DEPTH:
365                 goto notyet;
366         notyet:
367         default:
368                 if (ops->control)
369                         ops->control(drv, control, chan);
370                 break;
371         }
372 }
373
374
375 /*
376  * initialize the MIDI status
377  */
378 void
379 snd_midi_channel_set_clear(snd_midi_channel_set_t *chset)
380 {
381         int i;
382
383         chset->midi_mode = SNDRV_MIDI_MODE_GM;
384         chset->gs_master_volume = 127;
385
386         for (i = 0; i < chset->max_channels; i++) {
387                 snd_midi_channel_t *chan = chset->channels + i;
388                 memset(chan->note, 0, sizeof(chan->note));
389
390                 chan->midi_aftertouch = 0;
391                 chan->midi_pressure = 0;
392                 chan->midi_program = 0;
393                 chan->midi_pitchbend = 0;
394                 snd_midi_reset_controllers(chan);
395                 chan->gm_rpn_pitch_bend_range = 256; /* 2 semitones */
396                 chan->gm_rpn_fine_tuning = 0;
397                 chan->gm_rpn_coarse_tuning = 0;
398
399                 if (i == 9)
400                         chan->drum_channel = 1;
401                 else
402                         chan->drum_channel = 0;
403         }
404 }
405
406 /*
407  * Process a rpn message.
408  */
409 static void
410 rpn(snd_midi_op_t *ops, void *drv, snd_midi_channel_t *chan,
411     snd_midi_channel_set_t *chset)
412 {
413         int type;
414         int val;
415
416         if (chset->midi_mode != SNDRV_MIDI_MODE_NONE) {
417                 type = (chan->control[MIDI_CTL_REGIST_PARM_NUM_MSB] << 8) |
418                         chan->control[MIDI_CTL_REGIST_PARM_NUM_LSB];
419                 val = (chan->control[MIDI_CTL_MSB_DATA_ENTRY] << 7) |
420                         chan->control[MIDI_CTL_LSB_DATA_ENTRY];
421
422                 switch (type) {
423                 case 0x0000: /* Pitch bend sensitivity */
424                         /* MSB only / 1 semitone per 128 */
425                         chan->gm_rpn_pitch_bend_range = val;
426                         break;
427                                         
428                 case 0x0001: /* fine tuning: */
429                         /* MSB/LSB, 8192=center, 100/8192 cent step */
430                         chan->gm_rpn_fine_tuning = val - 8192;
431                         break;
432
433                 case 0x0002: /* coarse tuning */
434                         /* MSB only / 8192=center, 1 semitone per 128 */
435                         chan->gm_rpn_coarse_tuning = val - 8192;
436                         break;
437
438                 case 0x7F7F: /* "lock-in" RPN */
439                         /* ignored */
440                         break;
441                 }
442         }
443         /* should call nrpn or rpn callback here.. */
444 }
445
446 /*
447  * Process an nrpn message.
448  */
449 static void
450 nrpn(snd_midi_op_t *ops, void *drv, snd_midi_channel_t *chan,
451      snd_midi_channel_set_t *chset)
452 {
453         /* parse XG NRPNs here if possible */
454         if (ops->nrpn)
455                 ops->nrpn(drv, chan, chset);
456 }
457
458
459 /*
460  * convert channel parameter in GS sysex
461  */
462 static int
463 get_channel(unsigned char cmd)
464 {
465         int p = cmd & 0x0f;
466         if (p == 0)
467                 p = 9;
468         else if (p < 10)
469                 p--;
470         return p;
471 }
472
473
474 /*
475  * Process a sysex message.
476  */
477 static void
478 sysex(snd_midi_op_t *ops, void *private, unsigned char *buf, int len, snd_midi_channel_set_t *chset)
479 {
480         /* GM on */
481         static unsigned char gm_on_macro[] = {
482                 0x7e,0x7f,0x09,0x01,
483         };
484         /* XG on */
485         static unsigned char xg_on_macro[] = {
486                 0x43,0x10,0x4c,0x00,0x00,0x7e,0x00,
487         };
488         /* GS prefix
489          * drum channel: XX=0x1?(channel), YY=0x15, ZZ=on/off
490          * reverb mode: XX=0x01, YY=0x30, ZZ=0-7
491          * chorus mode: XX=0x01, YY=0x38, ZZ=0-7
492          * master vol:  XX=0x00, YY=0x04, ZZ=0-127
493          */
494         static unsigned char gs_pfx_macro[] = {
495                 0x41,0x10,0x42,0x12,0x40,/*XX,YY,ZZ*/
496         };
497
498         int parsed = SNDRV_MIDI_SYSEX_NOT_PARSED;
499
500         if (len <= 0 || buf[0] != 0xf0)
501                 return;
502         /* skip first byte */
503         buf++;
504         len--;
505
506         /* GM on */
507         if (len >= (int)sizeof(gm_on_macro) &&
508             memcmp(buf, gm_on_macro, sizeof(gm_on_macro)) == 0) {
509                 if (chset->midi_mode != SNDRV_MIDI_MODE_GS &&
510                     chset->midi_mode != SNDRV_MIDI_MODE_XG) {
511                         chset->midi_mode = SNDRV_MIDI_MODE_GM;
512                         reset_all_channels(chset);
513                         parsed = SNDRV_MIDI_SYSEX_GM_ON;
514                 }
515         }
516
517         /* GS macros */
518         else if (len >= 8 &&
519                  memcmp(buf, gs_pfx_macro, sizeof(gs_pfx_macro)) == 0) {
520                 if (chset->midi_mode != SNDRV_MIDI_MODE_GS &&
521                     chset->midi_mode != SNDRV_MIDI_MODE_XG)
522                         chset->midi_mode = SNDRV_MIDI_MODE_GS;
523
524                 if (buf[5] == 0x00 && buf[6] == 0x7f && buf[7] == 0x00) {
525                         /* GS reset */
526                         parsed = SNDRV_MIDI_SYSEX_GS_RESET;
527                         reset_all_channels(chset);
528                 }
529
530                 else if ((buf[5] & 0xf0) == 0x10 && buf[6] == 0x15) {
531                         /* drum pattern */
532                         int p = get_channel(buf[5]);
533                         if (p < chset->max_channels) {
534                                 parsed = SNDRV_MIDI_SYSEX_GS_DRUM_CHANNEL;
535                                 if (buf[7])
536                                         chset->channels[p].drum_channel = 1;
537                                 else
538                                         chset->channels[p].drum_channel = 0;
539                         }
540
541                 } else if ((buf[5] & 0xf0) == 0x10 && buf[6] == 0x21) {
542                         /* program */
543                         int p = get_channel(buf[5]);
544                         if (p < chset->max_channels &&
545                             ! chset->channels[p].drum_channel) {
546                                 parsed = SNDRV_MIDI_SYSEX_GS_DRUM_CHANNEL;
547                                 chset->channels[p].midi_program = buf[7];
548                         }
549
550                 } else if (buf[5] == 0x01 && buf[6] == 0x30) {
551                         /* reverb mode */
552                         parsed = SNDRV_MIDI_SYSEX_GS_REVERB_MODE;
553                         chset->gs_reverb_mode = buf[7];
554
555                 } else if (buf[5] == 0x01 && buf[6] == 0x38) {
556                         /* chorus mode */
557                         parsed = SNDRV_MIDI_SYSEX_GS_CHORUS_MODE;
558                         chset->gs_chorus_mode = buf[7];
559
560                 } else if (buf[5] == 0x00 && buf[6] == 0x04) {
561                         /* master volume */
562                         parsed = SNDRV_MIDI_SYSEX_GS_MASTER_VOLUME;
563                         chset->gs_master_volume = buf[7];
564
565                 }
566         }
567
568         /* XG on */
569         else if (len >= (int)sizeof(xg_on_macro) &&
570                  memcmp(buf, xg_on_macro, sizeof(xg_on_macro)) == 0) {
571                 int i;
572                 chset->midi_mode = SNDRV_MIDI_MODE_XG;
573                 parsed = SNDRV_MIDI_SYSEX_XG_ON;
574                 /* reset CC#0 for drums */
575                 for (i = 0; i < chset->max_channels; i++) {
576                         if (chset->channels[i].drum_channel)
577                                 chset->channels[i].control[MIDI_CTL_MSB_BANK] = 127;
578                         else
579                                 chset->channels[i].control[MIDI_CTL_MSB_BANK] = 0;
580                 }
581         }
582
583         if (ops->sysex)
584                 ops->sysex(private, buf - 1, len + 1, parsed, chset);
585 }
586
587 /*
588  * all sound off
589  */
590 static void
591 all_sounds_off(snd_midi_op_t *ops, void *drv, snd_midi_channel_t *chan)
592 {
593         int n;
594
595         if (! ops->note_terminate)
596                 return;
597         for (n = 0; n < 128; n++) {
598                 if (chan->note[n]) {
599                         ops->note_terminate(drv, n, chan);
600                         chan->note[n] = 0;
601                 }
602         }
603 }
604
605 /*
606  * all notes off
607  */
608 static void
609 all_notes_off(snd_midi_op_t *ops, void *drv, snd_midi_channel_t *chan)
610 {
611         int n;
612
613         if (! ops->note_off)
614                 return;
615         for (n = 0; n < 128; n++) {
616                 if (chan->note[n] == SNDRV_MIDI_NOTE_ON)
617                         note_off(ops, drv, chan, n, 0);
618         }
619 }
620
621 /*
622  * Initialise a single midi channel control block.
623  */
624 static void snd_midi_channel_init(snd_midi_channel_t *p, int n)
625 {
626         if (p == NULL)
627                 return;
628
629         memset(p, 0, sizeof(snd_midi_channel_t));
630         p->private = NULL;
631         p->number = n;
632
633         snd_midi_reset_controllers(p);
634         p->gm_rpn_pitch_bend_range = 256; /* 2 semitones */
635         p->gm_rpn_fine_tuning = 0;
636         p->gm_rpn_coarse_tuning = 0;
637
638         if (n == 9)
639                 p->drum_channel = 1;    /* Default ch 10 as drums */
640 }
641
642 /*
643  * Allocate and initialise a set of midi channel control blocks.
644  */
645 static snd_midi_channel_t *snd_midi_channel_init_set(int n)
646 {
647         snd_midi_channel_t *chan;
648         int  i;
649
650         chan = kmalloc(n * sizeof(snd_midi_channel_t), GFP_KERNEL);
651         if (chan) {
652                 for (i = 0; i < n; i++)
653                         snd_midi_channel_init(chan+i, i);
654         }
655
656         return chan;
657 }
658
659 /*
660  * reset all midi channels
661  */
662 static void
663 reset_all_channels(snd_midi_channel_set_t *chset)
664 {
665         int ch;
666         for (ch = 0; ch < chset->max_channels; ch++) {
667                 snd_midi_channel_t *chan = chset->channels + ch;
668                 snd_midi_reset_controllers(chan);
669                 chan->gm_rpn_pitch_bend_range = 256; /* 2 semitones */
670                 chan->gm_rpn_fine_tuning = 0;
671                 chan->gm_rpn_coarse_tuning = 0;
672
673                 if (ch == 9)
674                         chan->drum_channel = 1;
675                 else
676                         chan->drum_channel = 0;
677         }
678 }
679
680
681 /*
682  * Allocate and initialise a midi channel set.
683  */
684 snd_midi_channel_set_t *snd_midi_channel_alloc_set(int n)
685 {
686         snd_midi_channel_set_t *chset;
687
688         chset = kmalloc(sizeof(*chset), GFP_KERNEL);
689         if (chset) {
690                 chset->channels = snd_midi_channel_init_set(n);
691                 chset->private_data = NULL;
692                 chset->max_channels = n;
693         }
694         return chset;
695 }
696
697 /*
698  * Reset the midi controllers on a particular channel to default values.
699  */
700 static void snd_midi_reset_controllers(snd_midi_channel_t *chan)
701 {
702         memset(chan->control, 0, sizeof(chan->control));
703         chan->gm_volume = 127;
704         chan->gm_expression = 127;
705         chan->gm_pan = 64;
706 }
707
708
709 /*
710  * Free a midi channel set.
711  */
712 void snd_midi_channel_free_set(snd_midi_channel_set_t *chset)
713 {
714         if (chset == NULL)
715                 return;
716         kfree(chset->channels);
717         kfree(chset);
718 }
719
720 static int __init alsa_seq_midi_emul_init(void)
721 {
722         return 0;
723 }
724
725 static void __exit alsa_seq_midi_emul_exit(void)
726 {
727 }
728
729 module_init(alsa_seq_midi_emul_init)
730 module_exit(alsa_seq_midi_emul_exit)
731
732 EXPORT_SYMBOL(snd_midi_process_event);
733 EXPORT_SYMBOL(snd_midi_channel_set_clear);
734 EXPORT_SYMBOL(snd_midi_channel_alloc_set);
735 EXPORT_SYMBOL(snd_midi_channel_free_set);