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 = max(voice_time, vp2->time); 184 } 185 } else { 186 /* allocate 2op voice */ 187 if ((chan_4op_1) || (chan_4op_2)) 188 /* use bounded channels for 2op, CHEAP */ 189 bp++; 190 else if (vp->state) 191 /* kill one voice on 2op channel, CHEAP */ 192 bp++; 193 /* raise kill cost to EXPENSIVE for all channels */ 194 if (vp->state) 195 bp++; 196 } 197 if (voice_time < bp->time) { 198 bp->time = voice_time; 199 bp->voice = i; 200 } 201 } 202 203 for (i = 0; i < END; i++) { 204 if (best[i].voice >= 0) { 205 #ifdef DEBUG_ALLOC 206 printk(KERN_DEBUG "%s %iop allocation on voice %i\n", 207 alloc_type[i], instr_4op ? 4 : 2, 208 best[i].voice); 209 #endif 210 return best[i].voice; 211 } 212 } 213 /* not found */ 214 return -1; 215 } 216 217 /* ------------------------------ */ 218 219 /* 220 * System timer interrupt function 221 */ 222 void snd_opl3_timer_func(struct timer_list *t) 223 { 224 225 struct snd_opl3 *opl3 = from_timer(opl3, t, tlist); 226 unsigned long flags; 227 int again = 0; 228 int i; 229 230 spin_lock_irqsave(&opl3->voice_lock, flags); 231 for (i = 0; i < opl3->max_voices; i++) { 232 struct snd_opl3_voice *vp = &opl3->voices[i]; 233 if (vp->state > 0 && vp->note_off_check) { 234 if (vp->note_off == jiffies) 235 snd_opl3_note_off_unsafe(opl3, vp->note, 0, 236 vp->chan); 237 else 238 again++; 239 } 240 } 241 spin_unlock_irqrestore(&opl3->voice_lock, flags); 242 243 spin_lock_irqsave(&opl3->sys_timer_lock, flags); 244 if (again) 245 mod_timer(&opl3->tlist, jiffies + 1); /* invoke again */ 246 else 247 opl3->sys_timer_status = 0; 248 spin_unlock_irqrestore(&opl3->sys_timer_lock, flags); 249 } 250 251 /* 252 * Start system timer 253 */ 254 static void snd_opl3_start_timer(struct snd_opl3 *opl3) 255 { 256 unsigned long flags; 257 spin_lock_irqsave(&opl3->sys_timer_lock, flags); 258 if (! opl3->sys_timer_status) { 259 mod_timer(&opl3->tlist, jiffies + 1); 260 opl3->sys_timer_status = 1; 261 } 262 spin_unlock_irqrestore(&opl3->sys_timer_lock, flags); 263 } 264 265 /* ------------------------------ */ 266 267 268 static const int snd_opl3_oss_map[MAX_OPL3_VOICES] = { 269 0, 1, 2, 9, 10, 11, 6, 7, 8, 15, 16, 17, 3, 4 ,5, 12, 13, 14 270 }; 271 272 /* 273 * Start a note. 274 */ 275 void snd_opl3_note_on(void *p, int note, int vel, struct snd_midi_channel *chan) 276 { 277 struct snd_opl3 *opl3; 278 int instr_4op; 279 280 int voice; 281 struct snd_opl3_voice *vp, *vp2; 282 unsigned short connect_mask; 283 unsigned char connection; 284 unsigned char vol_op[4]; 285 286 int extra_prg = 0; 287 288 unsigned short reg_side; 289 unsigned char op_offset; 290 unsigned char voice_offset; 291 unsigned short opl3_reg; 292 unsigned char reg_val; 293 unsigned char prg, bank; 294 295 int key = note; 296 unsigned char fnum, blocknum; 297 int i; 298 299 struct fm_patch *patch; 300 struct fm_instrument *fm; 301 unsigned long flags; 302 303 opl3 = p; 304 305 #ifdef DEBUG_MIDI 306 snd_printk(KERN_DEBUG "Note on, ch %i, inst %i, note %i, vel %i\n", 307 chan->number, chan->midi_program, note, vel); 308 #endif 309 310 /* in SYNTH mode, application takes care of voices */ 311 /* in SEQ mode, drum voice numbers are notes on drum channel */ 312 if (opl3->synth_mode == SNDRV_OPL3_MODE_SEQ) { 313 if (chan->drum_channel) { 314 /* percussion instruments are located in bank 128 */ 315 bank = 128; 316 prg = note; 317 } else { 318 bank = chan->gm_bank_select; 319 prg = chan->midi_program; 320 } 321 } else { 322 /* Prepare for OSS mode */ 323 if (chan->number >= MAX_OPL3_VOICES) 324 return; 325 326 /* OSS instruments are located in bank 127 */ 327 bank = 127; 328 prg = chan->midi_program; 329 } 330 331 spin_lock_irqsave(&opl3->voice_lock, flags); 332 333 if (use_internal_drums) { 334 snd_opl3_drum_switch(opl3, note, vel, 1, chan); 335 spin_unlock_irqrestore(&opl3->voice_lock, flags); 336 return; 337 } 338 339 __extra_prg: 340 patch = snd_opl3_find_patch(opl3, prg, bank, 0); 341 if (!patch) { 342 spin_unlock_irqrestore(&opl3->voice_lock, flags); 343 return; 344 } 345 346 fm = &patch->inst; 347 switch (patch->type) { 348 case FM_PATCH_OPL2: 349 instr_4op = 0; 350 break; 351 case FM_PATCH_OPL3: 352 if (opl3->hardware >= OPL3_HW_OPL3) { 353 instr_4op = 1; 354 break; 355 } 356 fallthrough; 357 default: 358 spin_unlock_irqrestore(&opl3->voice_lock, flags); 359 return; 360 } 361 #ifdef DEBUG_MIDI 362 snd_printk(KERN_DEBUG " --> OPL%i instrument: %s\n", 363 instr_4op ? 3 : 2, patch->name); 364 #endif 365 /* in SYNTH mode, application takes care of voices */ 366 /* in SEQ mode, allocate voice on free OPL3 channel */ 367 if (opl3->synth_mode == SNDRV_OPL3_MODE_SEQ) { 368 voice = opl3_get_voice(opl3, instr_4op, chan); 369 } else { 370 /* remap OSS voice */ 371 voice = snd_opl3_oss_map[chan->number]; 372 } 373 374 if (voice < 0) { 375 spin_unlock_irqrestore(&opl3->voice_lock, flags); 376 return; 377 } 378 379 if (voice < MAX_OPL2_VOICES) { 380 /* Left register block for voices 0 .. 8 */ 381 reg_side = OPL3_LEFT; 382 voice_offset = voice; 383 connect_mask = (OPL3_LEFT_4OP_0 << voice_offset) & 0x07; 384 } else { 385 /* Right register block for voices 9 .. 17 */ 386 reg_side = OPL3_RIGHT; 387 voice_offset = voice - MAX_OPL2_VOICES; 388 connect_mask = (OPL3_RIGHT_4OP_0 << voice_offset) & 0x38; 389 } 390 391 /* kill voice on channel */ 392 vp = &opl3->voices[voice]; 393 if (vp->state > 0) { 394 opl3_reg = reg_side | (OPL3_REG_KEYON_BLOCK + voice_offset); 395 reg_val = vp->keyon_reg & ~OPL3_KEYON_BIT; 396 opl3->command(opl3, opl3_reg, reg_val); 397 } 398 if (instr_4op) { 399 vp2 = &opl3->voices[voice + 3]; 400 if (vp2->state > 0) { 401 opl3_reg = reg_side | (OPL3_REG_KEYON_BLOCK + 402 voice_offset + 3); 403 reg_val = vp->keyon_reg & ~OPL3_KEYON_BIT; 404 opl3->command(opl3, opl3_reg, reg_val); 405 } 406 } 407 408 /* set connection register */ 409 if (instr_4op) { 410 if ((opl3->connection_reg ^ connect_mask) & connect_mask) { 411 opl3->connection_reg |= connect_mask; 412 /* set connection bit */ 413 opl3_reg = OPL3_RIGHT | OPL3_REG_CONNECTION_SELECT; 414 opl3->command(opl3, opl3_reg, opl3->connection_reg); 415 } 416 } else { 417 if ((opl3->connection_reg ^ ~connect_mask) & connect_mask) { 418 opl3->connection_reg &= ~connect_mask; 419 /* clear connection bit */ 420 opl3_reg = OPL3_RIGHT | OPL3_REG_CONNECTION_SELECT; 421 opl3->command(opl3, opl3_reg, opl3->connection_reg); 422 } 423 } 424 425 #ifdef DEBUG_MIDI 426 snd_printk(KERN_DEBUG " --> setting OPL3 connection: 0x%x\n", 427 opl3->connection_reg); 428 #endif 429 /* 430 * calculate volume depending on connection 431 * between FM operators (see include/opl3.h) 432 */ 433 for (i = 0; i < (instr_4op ? 4 : 2); i++) 434 vol_op[i] = fm->op[i].ksl_level; 435 436 connection = fm->feedback_connection[0] & 0x01; 437 if (instr_4op) { 438 connection <<= 1; 439 connection |= fm->feedback_connection[1] & 0x01; 440 441 snd_opl3_calc_volume(&vol_op[3], vel, chan); 442 switch (connection) { 443 case 0x03: 444 snd_opl3_calc_volume(&vol_op[2], vel, chan); 445 fallthrough; 446 case 0x02: 447 snd_opl3_calc_volume(&vol_op[0], vel, chan); 448 break; 449 case 0x01: 450 snd_opl3_calc_volume(&vol_op[1], vel, chan); 451 } 452 } else { 453 snd_opl3_calc_volume(&vol_op[1], vel, chan); 454 if (connection) 455 snd_opl3_calc_volume(&vol_op[0], vel, chan); 456 } 457 458 /* Program the FM voice characteristics */ 459 for (i = 0; i < (instr_4op ? 4 : 2); i++) { 460 #ifdef DEBUG_MIDI 461 snd_printk(KERN_DEBUG " --> programming operator %i\n", i); 462 #endif 463 op_offset = snd_opl3_regmap[voice_offset][i]; 464 465 /* Set OPL3 AM_VIB register of requested voice/operator */ 466 reg_val = fm->op[i].am_vib; 467 opl3_reg = reg_side | (OPL3_REG_AM_VIB + op_offset); 468 opl3->command(opl3, opl3_reg, reg_val); 469 470 /* Set OPL3 KSL_LEVEL register of requested voice/operator */ 471 reg_val = vol_op[i]; 472 opl3_reg = reg_side | (OPL3_REG_KSL_LEVEL + op_offset); 473 opl3->command(opl3, opl3_reg, reg_val); 474 475 /* Set OPL3 ATTACK_DECAY register of requested voice/operator */ 476 reg_val = fm->op[i].attack_decay; 477 opl3_reg = reg_side | (OPL3_REG_ATTACK_DECAY + op_offset); 478 opl3->command(opl3, opl3_reg, reg_val); 479 480 /* Set OPL3 SUSTAIN_RELEASE register of requested voice/operator */ 481 reg_val = fm->op[i].sustain_release; 482 opl3_reg = reg_side | (OPL3_REG_SUSTAIN_RELEASE + op_offset); 483 opl3->command(opl3, opl3_reg, reg_val); 484 485 /* Select waveform */ 486 reg_val = fm->op[i].wave_select; 487 opl3_reg = reg_side | (OPL3_REG_WAVE_SELECT + op_offset); 488 opl3->command(opl3, opl3_reg, reg_val); 489 } 490 491 /* Set operator feedback and 2op inter-operator connection */ 492 reg_val = fm->feedback_connection[0]; 493 /* Set output voice connection */ 494 reg_val |= OPL3_STEREO_BITS; 495 if (chan->gm_pan < 43) 496 reg_val &= ~OPL3_VOICE_TO_RIGHT; 497 if (chan->gm_pan > 85) 498 reg_val &= ~OPL3_VOICE_TO_LEFT; 499 opl3_reg = reg_side | (OPL3_REG_FEEDBACK_CONNECTION + voice_offset); 500 opl3->command(opl3, opl3_reg, reg_val); 501 502 if (instr_4op) { 503 /* Set 4op inter-operator connection */ 504 reg_val = fm->feedback_connection[1] & OPL3_CONNECTION_BIT; 505 /* Set output voice connection */ 506 reg_val |= OPL3_STEREO_BITS; 507 if (chan->gm_pan < 43) 508 reg_val &= ~OPL3_VOICE_TO_RIGHT; 509 if (chan->gm_pan > 85) 510 reg_val &= ~OPL3_VOICE_TO_LEFT; 511 opl3_reg = reg_side | (OPL3_REG_FEEDBACK_CONNECTION + 512 voice_offset + 3); 513 opl3->command(opl3, opl3_reg, reg_val); 514 } 515 516 /* 517 * Special treatment of percussion notes for fm: 518 * Requested pitch is really program, and pitch for 519 * device is whatever was specified in the patch library. 520 */ 521 if (fm->fix_key) 522 note = fm->fix_key; 523 /* 524 * use transpose if defined in patch library 525 */ 526 if (fm->trnsps) 527 note += (fm->trnsps - 64); 528 529 snd_opl3_calc_pitch(&fnum, &blocknum, note, chan); 530 531 /* Set OPL3 FNUM_LOW register of requested voice */ 532 opl3_reg = reg_side | (OPL3_REG_FNUM_LOW + voice_offset); 533 opl3->command(opl3, opl3_reg, fnum); 534 535 opl3->voices[voice].keyon_reg = blocknum; 536 537 /* Set output sound flag */ 538 blocknum |= OPL3_KEYON_BIT; 539 540 #ifdef DEBUG_MIDI 541 snd_printk(KERN_DEBUG " --> trigger voice %i\n", voice); 542 #endif 543 /* Set OPL3 KEYON_BLOCK register of requested voice */ 544 opl3_reg = reg_side | (OPL3_REG_KEYON_BLOCK + voice_offset); 545 opl3->command(opl3, opl3_reg, blocknum); 546 547 /* kill note after fixed duration (in centiseconds) */ 548 if (fm->fix_dur) { 549 opl3->voices[voice].note_off = jiffies + 550 (fm->fix_dur * HZ) / 100; 551 snd_opl3_start_timer(opl3); 552 opl3->voices[voice].note_off_check = 1; 553 } else 554 opl3->voices[voice].note_off_check = 0; 555 556 /* get extra pgm, but avoid possible loops */ 557 extra_prg = (extra_prg) ? 0 : fm->modes; 558 559 /* do the bookkeeping */ 560 vp->time = opl3->use_time++; 561 vp->note = key; 562 vp->chan = chan; 563 564 if (instr_4op) { 565 vp->state = SNDRV_OPL3_ST_ON_4OP; 566 567 vp2 = &opl3->voices[voice + 3]; 568 vp2->time = opl3->use_time++; 569 vp2->note = key; 570 vp2->chan = chan; 571 vp2->state = SNDRV_OPL3_ST_NOT_AVAIL; 572 } else { 573 if (vp->state == SNDRV_OPL3_ST_ON_4OP) { 574 /* 4op killed by 2op, release bounded voice */ 575 vp2 = &opl3->voices[voice + 3]; 576 vp2->time = opl3->use_time++; 577 vp2->state = SNDRV_OPL3_ST_OFF; 578 } 579 vp->state = SNDRV_OPL3_ST_ON_2OP; 580 } 581 582 #ifdef DEBUG_ALLOC 583 debug_alloc(opl3, "note on ", voice); 584 #endif 585 586 /* allocate extra program if specified in patch library */ 587 if (extra_prg) { 588 if (extra_prg > 128) { 589 bank = 128; 590 /* percussions start at 35 */ 591 prg = extra_prg - 128 + 35 - 1; 592 } else { 593 bank = 0; 594 prg = extra_prg - 1; 595 } 596 #ifdef DEBUG_MIDI 597 snd_printk(KERN_DEBUG " *** allocating extra program\n"); 598 #endif 599 goto __extra_prg; 600 } 601 spin_unlock_irqrestore(&opl3->voice_lock, flags); 602 } 603 604 static void snd_opl3_kill_voice(struct snd_opl3 *opl3, int voice) 605 { 606 unsigned short reg_side; 607 unsigned char voice_offset; 608 unsigned short opl3_reg; 609 610 struct snd_opl3_voice *vp, *vp2; 611 612 if (snd_BUG_ON(voice >= MAX_OPL3_VOICES)) 613 return; 614 615 vp = &opl3->voices[voice]; 616 if (voice < MAX_OPL2_VOICES) { 617 /* Left register block for voices 0 .. 8 */ 618 reg_side = OPL3_LEFT; 619 voice_offset = voice; 620 } else { 621 /* Right register block for voices 9 .. 17 */ 622 reg_side = OPL3_RIGHT; 623 voice_offset = voice - MAX_OPL2_VOICES; 624 } 625 626 /* kill voice */ 627 #ifdef DEBUG_MIDI 628 snd_printk(KERN_DEBUG " --> kill voice %i\n", voice); 629 #endif 630 opl3_reg = reg_side | (OPL3_REG_KEYON_BLOCK + voice_offset); 631 /* clear Key ON bit */ 632 opl3->command(opl3, opl3_reg, vp->keyon_reg); 633 634 /* do the bookkeeping */ 635 vp->time = opl3->use_time++; 636 637 if (vp->state == SNDRV_OPL3_ST_ON_4OP) { 638 vp2 = &opl3->voices[voice + 3]; 639 640 vp2->time = opl3->use_time++; 641 vp2->state = SNDRV_OPL3_ST_OFF; 642 } 643 vp->state = SNDRV_OPL3_ST_OFF; 644 #ifdef DEBUG_ALLOC 645 debug_alloc(opl3, "note off", voice); 646 #endif 647 648 } 649 650 /* 651 * Release a note in response to a midi note off. 652 */ 653 static void snd_opl3_note_off_unsafe(void *p, int note, int vel, 654 struct snd_midi_channel *chan) 655 { 656 struct snd_opl3 *opl3; 657 658 int voice; 659 struct snd_opl3_voice *vp; 660 661 opl3 = p; 662 663 #ifdef DEBUG_MIDI 664 snd_printk(KERN_DEBUG "Note off, ch %i, inst %i, note %i\n", 665 chan->number, chan->midi_program, note); 666 #endif 667 668 if (opl3->synth_mode == SNDRV_OPL3_MODE_SEQ) { 669 if (chan->drum_channel && use_internal_drums) { 670 snd_opl3_drum_switch(opl3, note, vel, 0, chan); 671 return; 672 } 673 /* this loop will hopefully kill all extra voices, because 674 they are grouped by the same channel and note values */ 675 for (voice = 0; voice < opl3->max_voices; voice++) { 676 vp = &opl3->voices[voice]; 677 if (vp->state > 0 && vp->chan == chan && vp->note == note) { 678 snd_opl3_kill_voice(opl3, voice); 679 } 680 } 681 } else { 682 /* remap OSS voices */ 683 if (chan->number < MAX_OPL3_VOICES) { 684 voice = snd_opl3_oss_map[chan->number]; 685 snd_opl3_kill_voice(opl3, voice); 686 } 687 } 688 } 689 690 void snd_opl3_note_off(void *p, int note, int vel, 691 struct snd_midi_channel *chan) 692 { 693 struct snd_opl3 *opl3 = p; 694 unsigned long flags; 695 696 spin_lock_irqsave(&opl3->voice_lock, flags); 697 snd_opl3_note_off_unsafe(p, note, vel, chan); 698 spin_unlock_irqrestore(&opl3->voice_lock, flags); 699 } 700 701 /* 702 * key pressure change 703 */ 704 void snd_opl3_key_press(void *p, int note, int vel, struct snd_midi_channel *chan) 705 { 706 #ifdef DEBUG_MIDI 707 snd_printk(KERN_DEBUG "Key pressure, ch#: %i, inst#: %i\n", 708 chan->number, chan->midi_program); 709 #endif 710 } 711 712 /* 713 * terminate note 714 */ 715 void snd_opl3_terminate_note(void *p, int note, struct snd_midi_channel *chan) 716 { 717 #ifdef DEBUG_MIDI 718 snd_printk(KERN_DEBUG "Terminate note, ch#: %i, inst#: %i\n", 719 chan->number, chan->midi_program); 720 #endif 721 } 722 723 static void snd_opl3_update_pitch(struct snd_opl3 *opl3, int voice) 724 { 725 unsigned short reg_side; 726 unsigned char voice_offset; 727 unsigned short opl3_reg; 728 729 unsigned char fnum, blocknum; 730 731 struct snd_opl3_voice *vp; 732 733 if (snd_BUG_ON(voice >= MAX_OPL3_VOICES)) 734 return; 735 736 vp = &opl3->voices[voice]; 737 if (vp->chan == NULL) 738 return; /* not allocated? */ 739 740 if (voice < MAX_OPL2_VOICES) { 741 /* Left register block for voices 0 .. 8 */ 742 reg_side = OPL3_LEFT; 743 voice_offset = voice; 744 } else { 745 /* Right register block for voices 9 .. 17 */ 746 reg_side = OPL3_RIGHT; 747 voice_offset = voice - MAX_OPL2_VOICES; 748 } 749 750 snd_opl3_calc_pitch(&fnum, &blocknum, vp->note, vp->chan); 751 752 /* Set OPL3 FNUM_LOW register of requested voice */ 753 opl3_reg = reg_side | (OPL3_REG_FNUM_LOW + voice_offset); 754 opl3->command(opl3, opl3_reg, fnum); 755 756 vp->keyon_reg = blocknum; 757 758 /* Set output sound flag */ 759 blocknum |= OPL3_KEYON_BIT; 760 761 /* Set OPL3 KEYON_BLOCK register of requested voice */ 762 opl3_reg = reg_side | (OPL3_REG_KEYON_BLOCK + voice_offset); 763 opl3->command(opl3, opl3_reg, blocknum); 764 765 vp->time = opl3->use_time++; 766 } 767 768 /* 769 * Update voice pitch controller 770 */ 771 static void snd_opl3_pitch_ctrl(struct snd_opl3 *opl3, struct snd_midi_channel *chan) 772 { 773 int voice; 774 struct snd_opl3_voice *vp; 775 776 unsigned long flags; 777 778 spin_lock_irqsave(&opl3->voice_lock, flags); 779 780 if (opl3->synth_mode == SNDRV_OPL3_MODE_SEQ) { 781 for (voice = 0; voice < opl3->max_voices; voice++) { 782 vp = &opl3->voices[voice]; 783 if (vp->state > 0 && vp->chan == chan) { 784 snd_opl3_update_pitch(opl3, voice); 785 } 786 } 787 } else { 788 /* remap OSS voices */ 789 if (chan->number < MAX_OPL3_VOICES) { 790 voice = snd_opl3_oss_map[chan->number]; 791 snd_opl3_update_pitch(opl3, voice); 792 } 793 } 794 spin_unlock_irqrestore(&opl3->voice_lock, flags); 795 } 796 797 /* 798 * Deal with a controller type event. This includes all types of 799 * control events, not just the midi controllers 800 */ 801 void snd_opl3_control(void *p, int type, struct snd_midi_channel *chan) 802 { 803 struct snd_opl3 *opl3; 804 805 opl3 = p; 806 #ifdef DEBUG_MIDI 807 snd_printk(KERN_DEBUG "Controller, TYPE = %i, ch#: %i, inst#: %i\n", 808 type, chan->number, chan->midi_program); 809 #endif 810 811 switch (type) { 812 case MIDI_CTL_MSB_MODWHEEL: 813 if (chan->control[MIDI_CTL_MSB_MODWHEEL] > 63) 814 opl3->drum_reg |= OPL3_VIBRATO_DEPTH; 815 else 816 opl3->drum_reg &= ~OPL3_VIBRATO_DEPTH; 817 opl3->command(opl3, OPL3_LEFT | OPL3_REG_PERCUSSION, 818 opl3->drum_reg); 819 break; 820 case MIDI_CTL_E2_TREMOLO_DEPTH: 821 if (chan->control[MIDI_CTL_E2_TREMOLO_DEPTH] > 63) 822 opl3->drum_reg |= OPL3_TREMOLO_DEPTH; 823 else 824 opl3->drum_reg &= ~OPL3_TREMOLO_DEPTH; 825 opl3->command(opl3, OPL3_LEFT | OPL3_REG_PERCUSSION, 826 opl3->drum_reg); 827 break; 828 case MIDI_CTL_PITCHBEND: 829 snd_opl3_pitch_ctrl(opl3, chan); 830 break; 831 } 832 } 833 834 /* 835 * NRPN events 836 */ 837 void snd_opl3_nrpn(void *p, struct snd_midi_channel *chan, 838 struct snd_midi_channel_set *chset) 839 { 840 #ifdef DEBUG_MIDI 841 snd_printk(KERN_DEBUG "NRPN, ch#: %i, inst#: %i\n", 842 chan->number, chan->midi_program); 843 #endif 844 } 845 846 /* 847 * receive sysex 848 */ 849 void snd_opl3_sysex(void *p, unsigned char *buf, int len, 850 int parsed, struct snd_midi_channel_set *chset) 851 { 852 #ifdef DEBUG_MIDI 853 snd_printk(KERN_DEBUG "SYSEX\n"); 854 #endif 855 } 856
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.