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