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