emux_synth.c revision 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2
1/* 2 * Midi synth routines for the Emu8k/Emu10k1 3 * 4 * Copyright (C) 1999 Steve Ratcliffe 5 * Copyright (c) 1999-2000 Takashi Iwai <tiwai@suse.de> 6 * 7 * Contains code based on awe_wave.c by Takashi Iwai 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation; either version 2 of the License, or 12 * (at your option) any later version. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this program; if not, write to the Free Software 21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 * 23 */ 24 25#include "emux_voice.h" 26#include <sound/asoundef.h> 27 28/* 29 * Prototypes 30 */ 31 32/* 33 * Ensure a value is between two points 34 * macro evaluates its args more than once, so changed to upper-case. 35 */ 36#define LIMITVALUE(x, a, b) do { if ((x) < (a)) (x) = (a); else if ((x) > (b)) (x) = (b); } while (0) 37#define LIMITMAX(x, a) do {if ((x) > (a)) (x) = (a); } while (0) 38 39static int get_zone(snd_emux_t *emu, snd_emux_port_t *port, int *notep, int vel, snd_midi_channel_t *chan, snd_sf_zone_t **table); 40static int get_bank(snd_emux_port_t *port, snd_midi_channel_t *chan); 41static void terminate_note1(snd_emux_t *emu, int note, snd_midi_channel_t *chan, int free); 42static void exclusive_note_off(snd_emux_t *emu, snd_emux_port_t *port, int exclass); 43static void terminate_voice(snd_emux_t *emu, snd_emux_voice_t *vp, int free); 44static void update_voice(snd_emux_t *emu, snd_emux_voice_t *vp, int update); 45static void setup_voice(snd_emux_voice_t *vp); 46static int calc_pan(snd_emux_voice_t *vp); 47static int calc_volume(snd_emux_voice_t *vp); 48static int calc_pitch(snd_emux_voice_t *vp); 49 50 51/* 52 * Start a note. 53 */ 54void 55snd_emux_note_on(void *p, int note, int vel, snd_midi_channel_t *chan) 56{ 57 snd_emux_t *emu; 58 int i, key, nvoices; 59 snd_emux_voice_t *vp; 60 snd_sf_zone_t *table[SNDRV_EMUX_MAX_MULTI_VOICES]; 61 unsigned long flags; 62 snd_emux_port_t *port; 63 64 port = p; 65 snd_assert(port != NULL && chan != NULL, return); 66 67 emu = port->emu; 68 snd_assert(emu != NULL, return); 69 snd_assert(emu->ops.get_voice != NULL, return); 70 snd_assert(emu->ops.trigger != NULL, return); 71 72 key = note; /* remember the original note */ 73 nvoices = get_zone(emu, port, ¬e, vel, chan, table); 74 if (! nvoices) 75 return; 76 77 /* exclusive note off */ 78 for (i = 0; i < nvoices; i++) { 79 snd_sf_zone_t *zp = table[i]; 80 if (zp && zp->v.exclusiveClass) 81 exclusive_note_off(emu, port, zp->v.exclusiveClass); 82 } 83 84#if 0 // seems not necessary 85 /* Turn off the same note on the same channel. */ 86 terminate_note1(emu, key, chan, 0); 87#endif 88 89 spin_lock_irqsave(&emu->voice_lock, flags); 90 for (i = 0; i < nvoices; i++) { 91 92 /* set up each voice parameter */ 93 /* at this stage, we don't trigger the voice yet. */ 94 95 if (table[i] == NULL) 96 continue; 97 98 vp = emu->ops.get_voice(emu, port); 99 if (vp == NULL || vp->ch < 0) 100 continue; 101 snd_assert(vp->emu != NULL && vp->hw != NULL, return); 102 if (STATE_IS_PLAYING(vp->state)) 103 emu->ops.terminate(vp); 104 105 vp->time = emu->use_time++; 106 vp->chan = chan; 107 vp->port = port; 108 vp->key = key; 109 vp->note = note; 110 vp->velocity = vel; 111 vp->zone = table[i]; 112 if (vp->zone->sample) 113 vp->block = vp->zone->sample->block; 114 else 115 vp->block = NULL; 116 117 setup_voice(vp); 118 119 vp->state = SNDRV_EMUX_ST_STANDBY; 120 if (emu->ops.prepare) { 121 vp->state = SNDRV_EMUX_ST_OFF; 122 if (emu->ops.prepare(vp) >= 0) 123 vp->state = SNDRV_EMUX_ST_STANDBY; 124 } 125 } 126 127 /* start envelope now */ 128 for (i = 0; i < emu->max_voices; i++) { 129 vp = &emu->voices[i]; 130 if (vp->state == SNDRV_EMUX_ST_STANDBY && 131 vp->chan == chan) { 132 emu->ops.trigger(vp); 133 vp->state = SNDRV_EMUX_ST_ON; 134 vp->ontime = jiffies; /* remember the trigger timing */ 135 } 136 } 137 spin_unlock_irqrestore(&emu->voice_lock, flags); 138 139#ifdef SNDRV_EMUX_USE_RAW_EFFECT 140 if (port->port_mode == SNDRV_EMUX_PORT_MODE_OSS_SYNTH) { 141 /* clear voice position for the next note on this channel */ 142 snd_emux_effect_table_t *fx = chan->private; 143 if (fx) { 144 fx->flag[EMUX_FX_SAMPLE_START] = 0; 145 fx->flag[EMUX_FX_COARSE_SAMPLE_START] = 0; 146 } 147 } 148#endif 149} 150 151/* 152 * Release a note in response to a midi note off. 153 */ 154void 155snd_emux_note_off(void *p, int note, int vel, snd_midi_channel_t *chan) 156{ 157 int ch; 158 snd_emux_t *emu; 159 snd_emux_voice_t *vp; 160 unsigned long flags; 161 snd_emux_port_t *port; 162 163 port = p; 164 snd_assert(port != NULL && chan != NULL, return); 165 166 emu = port->emu; 167 snd_assert(emu != NULL, return); 168 snd_assert(emu->ops.release != NULL, return); 169 170 spin_lock_irqsave(&emu->voice_lock, flags); 171 for (ch = 0; ch < emu->max_voices; ch++) { 172 vp = &emu->voices[ch]; 173 if (STATE_IS_PLAYING(vp->state) && 174 vp->chan == chan && vp->key == note) { 175 vp->time = emu->use_time++; 176 vp->state = SNDRV_EMUX_ST_RELEASED; 177 if (vp->ontime == jiffies) { 178 /* if note-off is sent too shortly after 179 * note-on, emuX engine cannot produce the sound 180 * correctly. so we'll release this note 181 * a bit later via timer callback. 182 */ 183 vp->state = SNDRV_EMUX_ST_PENDING; 184 if (! emu->timer_active) { 185 emu->tlist.expires = jiffies + 1; 186 add_timer(&emu->tlist); 187 emu->timer_active = 1; 188 } 189 } else 190 /* ok now release the note */ 191 emu->ops.release(vp); 192 } 193 } 194 spin_unlock_irqrestore(&emu->voice_lock, flags); 195} 196 197/* 198 * timer callback 199 * 200 * release the pending note-offs 201 */ 202void snd_emux_timer_callback(unsigned long data) 203{ 204 snd_emux_t *emu = (snd_emux_t*) data; 205 snd_emux_voice_t *vp; 206 int ch, do_again = 0; 207 208 spin_lock(&emu->voice_lock); 209 for (ch = 0; ch < emu->max_voices; ch++) { 210 vp = &emu->voices[ch]; 211 if (vp->state == SNDRV_EMUX_ST_PENDING) { 212 if (vp->ontime == jiffies) 213 do_again++; /* release this at the next interrupt */ 214 else { 215 emu->ops.release(vp); 216 vp->state = SNDRV_EMUX_ST_RELEASED; 217 } 218 } 219 } 220 if (do_again) { 221 emu->tlist.expires = jiffies + 1; 222 add_timer(&emu->tlist); 223 emu->timer_active = 1; 224 } else 225 emu->timer_active = 0; 226 spin_unlock(&emu->voice_lock); 227} 228 229/* 230 * key pressure change 231 */ 232void 233snd_emux_key_press(void *p, int note, int vel, snd_midi_channel_t *chan) 234{ 235 int ch; 236 snd_emux_t *emu; 237 snd_emux_voice_t *vp; 238 unsigned long flags; 239 snd_emux_port_t *port; 240 241 port = p; 242 snd_assert(port != NULL && chan != NULL, return); 243 244 emu = port->emu; 245 snd_assert(emu != NULL, return); 246 snd_assert(emu->ops.update != NULL, return); 247 248 spin_lock_irqsave(&emu->voice_lock, flags); 249 for (ch = 0; ch < emu->max_voices; ch++) { 250 vp = &emu->voices[ch]; 251 if (vp->state == SNDRV_EMUX_ST_ON && 252 vp->chan == chan && vp->key == note) { 253 vp->velocity = vel; 254 update_voice(emu, vp, SNDRV_EMUX_UPDATE_VOLUME); 255 } 256 } 257 spin_unlock_irqrestore(&emu->voice_lock, flags); 258} 259 260 261/* 262 * Modulate the voices which belong to the channel 263 */ 264void 265snd_emux_update_channel(snd_emux_port_t *port, snd_midi_channel_t *chan, int update) 266{ 267 snd_emux_t *emu; 268 snd_emux_voice_t *vp; 269 int i; 270 unsigned long flags; 271 272 if (! update) 273 return; 274 275 emu = port->emu; 276 snd_assert(emu != NULL, return); 277 snd_assert(emu->ops.update != NULL, return); 278 279 spin_lock_irqsave(&emu->voice_lock, flags); 280 for (i = 0; i < emu->max_voices; i++) { 281 vp = &emu->voices[i]; 282 if (vp->chan == chan) 283 update_voice(emu, vp, update); 284 } 285 spin_unlock_irqrestore(&emu->voice_lock, flags); 286} 287 288/* 289 * Modulate all the voices which belong to the port. 290 */ 291void 292snd_emux_update_port(snd_emux_port_t *port, int update) 293{ 294 snd_emux_t *emu; 295 snd_emux_voice_t *vp; 296 int i; 297 unsigned long flags; 298 299 if (! update) 300 return; 301 302 emu = port->emu; 303 snd_assert(emu != NULL, return); 304 snd_assert(emu->ops.update != NULL, return); 305 306 spin_lock_irqsave(&emu->voice_lock, flags); 307 for (i = 0; i < emu->max_voices; i++) { 308 vp = &emu->voices[i]; 309 if (vp->port == port) 310 update_voice(emu, vp, update); 311 } 312 spin_unlock_irqrestore(&emu->voice_lock, flags); 313} 314 315 316/* 317 * Deal with a controler type event. This includes all types of 318 * control events, not just the midi controllers 319 */ 320void 321snd_emux_control(void *p, int type, snd_midi_channel_t *chan) 322{ 323 snd_emux_port_t *port; 324 325 port = p; 326 snd_assert(port != NULL && chan != NULL, return); 327 328 switch (type) { 329 case MIDI_CTL_MSB_MAIN_VOLUME: 330 case MIDI_CTL_MSB_EXPRESSION: 331 snd_emux_update_channel(port, chan, SNDRV_EMUX_UPDATE_VOLUME); 332 break; 333 334 case MIDI_CTL_MSB_PAN: 335 snd_emux_update_channel(port, chan, SNDRV_EMUX_UPDATE_PAN); 336 break; 337 338 case MIDI_CTL_SOFT_PEDAL: 339#ifdef SNDRV_EMUX_USE_RAW_EFFECT 340 /* FIXME: this is an emulation */ 341 snd_emux_send_effect(port, chan, EMUX_FX_CUTOFF, -160, 342 EMUX_FX_FLAG_ADD); 343#endif 344 break; 345 346 case MIDI_CTL_PITCHBEND: 347 snd_emux_update_channel(port, chan, SNDRV_EMUX_UPDATE_PITCH); 348 break; 349 350 case MIDI_CTL_MSB_MODWHEEL: 351 case MIDI_CTL_CHAN_PRESSURE: 352 snd_emux_update_channel(port, chan, 353 SNDRV_EMUX_UPDATE_FMMOD | 354 SNDRV_EMUX_UPDATE_FM2FRQ2); 355 break; 356 357 } 358 359 if (port->chset.midi_mode == SNDRV_MIDI_MODE_XG) { 360 snd_emux_xg_control(port, chan, type); 361 } 362} 363 364 365/* 366 * terminate note - if free flag is true, free the terminated voice 367 */ 368static void 369terminate_note1(snd_emux_t *emu, int note, snd_midi_channel_t *chan, int free) 370{ 371 int i; 372 snd_emux_voice_t *vp; 373 unsigned long flags; 374 375 spin_lock_irqsave(&emu->voice_lock, flags); 376 for (i = 0; i < emu->max_voices; i++) { 377 vp = &emu->voices[i]; 378 if (STATE_IS_PLAYING(vp->state) && vp->chan == chan && 379 vp->key == note) 380 terminate_voice(emu, vp, free); 381 } 382 spin_unlock_irqrestore(&emu->voice_lock, flags); 383} 384 385 386/* 387 * terminate note - exported for midi emulation 388 */ 389void 390snd_emux_terminate_note(void *p, int note, snd_midi_channel_t *chan) 391{ 392 snd_emux_t *emu; 393 snd_emux_port_t *port; 394 395 port = p; 396 snd_assert(port != NULL && chan != NULL, return); 397 398 emu = port->emu; 399 snd_assert(emu != NULL, return); 400 snd_assert(emu->ops.terminate != NULL, return); 401 402 terminate_note1(emu, note, chan, 1); 403} 404 405 406/* 407 * Terminate all the notes 408 */ 409void 410snd_emux_terminate_all(snd_emux_t *emu) 411{ 412 int i; 413 snd_emux_voice_t *vp; 414 unsigned long flags; 415 416 spin_lock_irqsave(&emu->voice_lock, flags); 417 for (i = 0; i < emu->max_voices; i++) { 418 vp = &emu->voices[i]; 419 if (STATE_IS_PLAYING(vp->state)) 420 terminate_voice(emu, vp, 0); 421 if (vp->state == SNDRV_EMUX_ST_OFF) { 422 if (emu->ops.free_voice) 423 emu->ops.free_voice(vp); 424 if (emu->ops.reset) 425 emu->ops.reset(emu, i); 426 } 427 vp->time = 0; 428 } 429 /* initialize allocation time */ 430 emu->use_time = 0; 431 spin_unlock_irqrestore(&emu->voice_lock, flags); 432} 433 434 435/* 436 * Terminate all voices associated with the given port 437 */ 438void 439snd_emux_sounds_off_all(snd_emux_port_t *port) 440{ 441 int i; 442 snd_emux_t *emu; 443 snd_emux_voice_t *vp; 444 unsigned long flags; 445 446 snd_assert(port != NULL, return); 447 emu = port->emu; 448 snd_assert(emu != NULL, return); 449 snd_assert(emu->ops.terminate != NULL, return); 450 451 spin_lock_irqsave(&emu->voice_lock, flags); 452 for (i = 0; i < emu->max_voices; i++) { 453 vp = &emu->voices[i]; 454 if (STATE_IS_PLAYING(vp->state) && 455 vp->port == port) 456 terminate_voice(emu, vp, 0); 457 if (vp->state == SNDRV_EMUX_ST_OFF) { 458 if (emu->ops.free_voice) 459 emu->ops.free_voice(vp); 460 if (emu->ops.reset) 461 emu->ops.reset(emu, i); 462 } 463 } 464 spin_unlock_irqrestore(&emu->voice_lock, flags); 465} 466 467 468/* 469 * Terminate all voices that have the same exclusive class. This 470 * is mainly for drums. 471 */ 472static void 473exclusive_note_off(snd_emux_t *emu, snd_emux_port_t *port, int exclass) 474{ 475 snd_emux_voice_t *vp; 476 int i; 477 unsigned long flags; 478 479 spin_lock_irqsave(&emu->voice_lock, flags); 480 for (i = 0; i < emu->max_voices; i++) { 481 vp = &emu->voices[i]; 482 if (STATE_IS_PLAYING(vp->state) && vp->port == port && 483 vp->reg.exclusiveClass == exclass) { 484 terminate_voice(emu, vp, 0); 485 } 486 } 487 spin_unlock_irqrestore(&emu->voice_lock, flags); 488} 489 490/* 491 * terminate a voice 492 * if free flag is true, call free_voice after termination 493 */ 494static void 495terminate_voice(snd_emux_t *emu, snd_emux_voice_t *vp, int free) 496{ 497 emu->ops.terminate(vp); 498 vp->time = emu->use_time++; 499 vp->chan = NULL; 500 vp->port = NULL; 501 vp->zone = NULL; 502 vp->block = NULL; 503 vp->state = SNDRV_EMUX_ST_OFF; 504 if (free && emu->ops.free_voice) 505 emu->ops.free_voice(vp); 506} 507 508 509/* 510 * Modulate the voice 511 */ 512static void 513update_voice(snd_emux_t *emu, snd_emux_voice_t *vp, int update) 514{ 515 if (!STATE_IS_PLAYING(vp->state)) 516 return; 517 518 if (vp->chan == NULL || vp->port == NULL) 519 return; 520 if (update & SNDRV_EMUX_UPDATE_VOLUME) 521 calc_volume(vp); 522 if (update & SNDRV_EMUX_UPDATE_PITCH) 523 calc_pitch(vp); 524 if (update & SNDRV_EMUX_UPDATE_PAN) { 525 if (! calc_pan(vp) && (update == SNDRV_EMUX_UPDATE_PAN)) 526 return; 527 } 528 emu->ops.update(vp, update); 529} 530 531 532#if 0 // not used 533/* table for volume target calculation */ 534static unsigned short voltarget[16] = { 535 0xEAC0, 0xE0C8, 0xD740, 0xCE20, 0xC560, 0xBD08, 0xB500, 0xAD58, 536 0xA5F8, 0x9EF0, 0x9830, 0x91C0, 0x8B90, 0x85A8, 0x8000, 0x7A90 537}; 538#endif 539 540#define LO_BYTE(v) ((v) & 0xff) 541#define HI_BYTE(v) (((v) >> 8) & 0xff) 542 543/* 544 * Sets up the voice structure by calculating some values that 545 * will be needed later. 546 */ 547static void 548setup_voice(snd_emux_voice_t *vp) 549{ 550 soundfont_voice_parm_t *parm; 551 int pitch; 552 553 /* copy the original register values */ 554 vp->reg = vp->zone->v; 555 556#ifdef SNDRV_EMUX_USE_RAW_EFFECT 557 snd_emux_setup_effect(vp); 558#endif 559 560 /* reset status */ 561 vp->apan = -1; 562 vp->avol = -1; 563 vp->apitch = -1; 564 565 calc_volume(vp); 566 calc_pitch(vp); 567 calc_pan(vp); 568 569 parm = &vp->reg.parm; 570 571 /* compute filter target and correct modulation parameters */ 572 if (LO_BYTE(parm->modatkhld) >= 0x80 && parm->moddelay >= 0x8000) { 573 parm->moddelay = 0xbfff; 574 pitch = (HI_BYTE(parm->pefe) << 4) + vp->apitch; 575 if (pitch > 0xffff) 576 pitch = 0xffff; 577 /* calculate filter target */ 578 vp->ftarget = parm->cutoff + LO_BYTE(parm->pefe); 579 LIMITVALUE(vp->ftarget, 0, 255); 580 vp->ftarget <<= 8; 581 } else { 582 vp->ftarget = parm->cutoff; 583 vp->ftarget <<= 8; 584 pitch = vp->apitch; 585 } 586 587 /* compute pitch target */ 588 if (pitch != 0xffff) { 589 vp->ptarget = 1 << (pitch >> 12); 590 if (pitch & 0x800) vp->ptarget += (vp->ptarget*0x102e)/0x2710; 591 if (pitch & 0x400) vp->ptarget += (vp->ptarget*0x764)/0x2710; 592 if (pitch & 0x200) vp->ptarget += (vp->ptarget*0x389)/0x2710; 593 vp->ptarget += (vp->ptarget >> 1); 594 if (vp->ptarget > 0xffff) vp->ptarget = 0xffff; 595 } else 596 vp->ptarget = 0xffff; 597 598 if (LO_BYTE(parm->modatkhld) >= 0x80) { 599 parm->modatkhld &= ~0xff; 600 parm->modatkhld |= 0x7f; 601 } 602 603 /* compute volume target and correct volume parameters */ 604 vp->vtarget = 0; 605#if 0 /* FIXME: this leads to some clicks.. */ 606 if (LO_BYTE(parm->volatkhld) >= 0x80 && parm->voldelay >= 0x8000) { 607 parm->voldelay = 0xbfff; 608 vp->vtarget = voltarget[vp->avol % 0x10] >> (vp->avol >> 4); 609 } 610#endif 611 612 if (LO_BYTE(parm->volatkhld) >= 0x80) { 613 parm->volatkhld &= ~0xff; 614 parm->volatkhld |= 0x7f; 615 } 616} 617 618/* 619 * calculate pitch parameter 620 */ 621static unsigned char pan_volumes[256] = { 6220x00,0x03,0x06,0x09,0x0c,0x0f,0x12,0x14,0x17,0x1a,0x1d,0x20,0x22,0x25,0x28,0x2a, 6230x2d,0x30,0x32,0x35,0x37,0x3a,0x3c,0x3f,0x41,0x44,0x46,0x49,0x4b,0x4d,0x50,0x52, 6240x54,0x57,0x59,0x5b,0x5d,0x60,0x62,0x64,0x66,0x68,0x6a,0x6c,0x6f,0x71,0x73,0x75, 6250x77,0x79,0x7b,0x7c,0x7e,0x80,0x82,0x84,0x86,0x88,0x89,0x8b,0x8d,0x8f,0x90,0x92, 6260x94,0x96,0x97,0x99,0x9a,0x9c,0x9e,0x9f,0xa1,0xa2,0xa4,0xa5,0xa7,0xa8,0xaa,0xab, 6270xad,0xae,0xaf,0xb1,0xb2,0xb3,0xb5,0xb6,0xb7,0xb9,0xba,0xbb,0xbc,0xbe,0xbf,0xc0, 6280xc1,0xc2,0xc3,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xcb,0xcc,0xcd,0xce,0xcf,0xd0,0xd1, 6290xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd7,0xd8,0xd9,0xda,0xdb,0xdc,0xdc,0xdd,0xde,0xdf, 6300xdf,0xe0,0xe1,0xe2,0xe2,0xe3,0xe4,0xe4,0xe5,0xe6,0xe6,0xe7,0xe8,0xe8,0xe9,0xe9, 6310xea,0xeb,0xeb,0xec,0xec,0xed,0xed,0xee,0xee,0xef,0xef,0xf0,0xf0,0xf1,0xf1,0xf1, 6320xf2,0xf2,0xf3,0xf3,0xf3,0xf4,0xf4,0xf5,0xf5,0xf5,0xf6,0xf6,0xf6,0xf7,0xf7,0xf7, 6330xf7,0xf8,0xf8,0xf8,0xf9,0xf9,0xf9,0xf9,0xf9,0xfa,0xfa,0xfa,0xfa,0xfb,0xfb,0xfb, 6340xfb,0xfb,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd, 6350xfd,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe, 6360xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 6370xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 638}; 639 640static int 641calc_pan(snd_emux_voice_t *vp) 642{ 643 snd_midi_channel_t *chan = vp->chan; 644 int pan; 645 646 /* pan & loop start (pan 8bit, MSB, 0:right, 0xff:left) */ 647 if (vp->reg.fixpan > 0) /* 0-127 */ 648 pan = 255 - (int)vp->reg.fixpan * 2; 649 else { 650 pan = chan->control[MIDI_CTL_MSB_PAN] - 64; 651 if (vp->reg.pan >= 0) /* 0-127 */ 652 pan += vp->reg.pan - 64; 653 pan = 127 - (int)pan * 2; 654 } 655 LIMITVALUE(pan, 0, 255); 656 657 if (vp->emu->linear_panning) { 658 /* assuming linear volume */ 659 if (pan != vp->apan) { 660 vp->apan = pan; 661 if (pan == 0) 662 vp->aaux = 0xff; 663 else 664 vp->aaux = (-pan) & 0xff; 665 return 1; 666 } else 667 return 0; 668 } else { 669 /* using volume table */ 670 if (vp->apan != (int)pan_volumes[pan]) { 671 vp->apan = pan_volumes[pan]; 672 vp->aaux = pan_volumes[255 - pan]; 673 return 1; 674 } 675 return 0; 676 } 677} 678 679 680/* 681 * calculate volume attenuation 682 * 683 * Voice volume is controlled by volume attenuation parameter. 684 * So volume becomes maximum when avol is 0 (no attenuation), and 685 * minimum when 255 (-96dB or silence). 686 */ 687 688/* tables for volume->attenuation calculation */ 689static unsigned char voltab1[128] = { 690 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 691 0x63, 0x2b, 0x29, 0x28, 0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 692 0x21, 0x20, 0x1f, 0x1e, 0x1e, 0x1d, 0x1c, 0x1b, 0x1b, 0x1a, 693 0x19, 0x19, 0x18, 0x17, 0x17, 0x16, 0x16, 0x15, 0x15, 0x14, 694 0x14, 0x13, 0x13, 0x13, 0x12, 0x12, 0x11, 0x11, 0x11, 0x10, 695 0x10, 0x10, 0x0f, 0x0f, 0x0f, 0x0e, 0x0e, 0x0e, 0x0e, 0x0d, 696 0x0d, 0x0d, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0b, 0x0b, 0x0b, 697 0x0b, 0x0a, 0x0a, 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 698 0x08, 0x08, 0x08, 0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x06, 699 0x06, 0x06, 0x06, 0x06, 0x05, 0x05, 0x05, 0x05, 0x05, 0x04, 700 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02, 701 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 702 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 703}; 704 705static unsigned char voltab2[128] = { 706 0x32, 0x31, 0x30, 0x2f, 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x2a, 707 0x29, 0x28, 0x27, 0x26, 0x25, 0x24, 0x24, 0x23, 0x22, 0x21, 708 0x21, 0x20, 0x1f, 0x1e, 0x1e, 0x1d, 0x1c, 0x1c, 0x1b, 0x1a, 709 0x1a, 0x19, 0x19, 0x18, 0x18, 0x17, 0x16, 0x16, 0x15, 0x15, 710 0x14, 0x14, 0x13, 0x13, 0x13, 0x12, 0x12, 0x11, 0x11, 0x10, 711 0x10, 0x10, 0x0f, 0x0f, 0x0f, 0x0e, 0x0e, 0x0e, 0x0d, 0x0d, 712 0x0d, 0x0c, 0x0c, 0x0c, 0x0b, 0x0b, 0x0b, 0x0b, 0x0a, 0x0a, 713 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x08, 0x08, 0x08, 714 0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x07, 0x06, 0x06, 0x06, 715 0x06, 0x06, 0x06, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 716 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03, 717 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 718 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 719}; 720 721static unsigned char expressiontab[128] = { 722 0x7f, 0x6c, 0x62, 0x5a, 0x54, 0x50, 0x4b, 0x48, 0x45, 0x42, 723 0x40, 0x3d, 0x3b, 0x39, 0x38, 0x36, 0x34, 0x33, 0x31, 0x30, 724 0x2f, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, 0x27, 0x26, 0x25, 725 0x24, 0x24, 0x23, 0x22, 0x21, 0x21, 0x20, 0x1f, 0x1e, 0x1e, 726 0x1d, 0x1d, 0x1c, 0x1b, 0x1b, 0x1a, 0x1a, 0x19, 0x18, 0x18, 727 0x17, 0x17, 0x16, 0x16, 0x15, 0x15, 0x15, 0x14, 0x14, 0x13, 728 0x13, 0x12, 0x12, 0x11, 0x11, 0x11, 0x10, 0x10, 0x0f, 0x0f, 729 0x0f, 0x0e, 0x0e, 0x0e, 0x0d, 0x0d, 0x0d, 0x0c, 0x0c, 0x0c, 730 0x0b, 0x0b, 0x0b, 0x0a, 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09, 731 0x08, 0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x06, 0x06, 0x06, 732 0x06, 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 733 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 734 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 735}; 736 737/* 738 * Magic to calculate the volume (actually attenuation) from all the 739 * voice and channels parameters. 740 */ 741static int 742calc_volume(snd_emux_voice_t *vp) 743{ 744 int vol; 745 int main_vol, expression_vol, master_vol; 746 snd_midi_channel_t *chan = vp->chan; 747 snd_emux_port_t *port = vp->port; 748 749 expression_vol = chan->control[MIDI_CTL_MSB_EXPRESSION]; 750 LIMITMAX(vp->velocity, 127); 751 LIMITVALUE(expression_vol, 0, 127); 752 if (port->port_mode == SNDRV_EMUX_PORT_MODE_OSS_SYNTH) { 753 /* 0 - 127 */ 754 main_vol = chan->control[MIDI_CTL_MSB_MAIN_VOLUME]; 755 vol = (vp->velocity * main_vol * expression_vol) / (127*127); 756 vol = vol * vp->reg.amplitude / 127; 757 758 LIMITVALUE(vol, 0, 127); 759 760 /* calc to attenuation */ 761 vol = snd_sf_vol_table[vol]; 762 763 } else { 764 main_vol = chan->control[MIDI_CTL_MSB_MAIN_VOLUME] * vp->reg.amplitude / 127; 765 LIMITVALUE(main_vol, 0, 127); 766 767 vol = voltab1[main_vol] + voltab2[vp->velocity]; 768 vol = (vol * 8) / 3; 769 vol += vp->reg.attenuation; 770 vol += ((0x100 - vol) * expressiontab[expression_vol])/128; 771 } 772 773 master_vol = port->chset.gs_master_volume; 774 LIMITVALUE(master_vol, 0, 127); 775 vol += snd_sf_vol_table[master_vol]; 776 vol += port->volume_atten; 777 778#ifdef SNDRV_EMUX_USE_RAW_EFFECT 779 if (chan->private) { 780 snd_emux_effect_table_t *fx = chan->private; 781 vol += fx->val[EMUX_FX_ATTEN]; 782 } 783#endif 784 785 LIMITVALUE(vol, 0, 255); 786 if (vp->avol == vol) 787 return 0; /* value unchanged */ 788 789 vp->avol = vol; 790 if (!SF_IS_DRUM_BANK(get_bank(port, chan)) 791 && LO_BYTE(vp->reg.parm.volatkhld) < 0x7d) { 792 int atten; 793 if (vp->velocity < 70) 794 atten = 70; 795 else 796 atten = vp->velocity; 797 vp->acutoff = (atten * vp->reg.parm.cutoff + 0xa0) >> 7; 798 } else { 799 vp->acutoff = vp->reg.parm.cutoff; 800 } 801 802 return 1; /* value changed */ 803} 804 805/* 806 * calculate pitch offset 807 * 808 * 0xE000 is no pitch offset at 44100Hz sample. 809 * Every 4096 is one octave. 810 */ 811 812static int 813calc_pitch(snd_emux_voice_t *vp) 814{ 815 snd_midi_channel_t *chan = vp->chan; 816 int offset; 817 818 /* calculate offset */ 819 if (vp->reg.fixkey >= 0) { 820 offset = (vp->reg.fixkey - vp->reg.root) * 4096 / 12; 821 } else { 822 offset = (vp->note - vp->reg.root) * 4096 / 12; 823 } 824 offset = (offset * vp->reg.scaleTuning) / 100; 825 offset += vp->reg.tune * 4096 / 1200; 826 if (chan->midi_pitchbend != 0) { 827 /* (128 * 8192: 1 semitone) ==> (4096: 12 semitones) */ 828 offset += chan->midi_pitchbend * chan->gm_rpn_pitch_bend_range / 3072; 829 } 830 831 /* tuning via RPN: 832 * coarse = -8192 to 8192 (100 cent per 128) 833 * fine = -8192 to 8192 (max=100cent) 834 */ 835 /* 4096 = 1200 cents in emu8000 parameter */ 836 offset += chan->gm_rpn_coarse_tuning * 4096 / (12 * 128); 837 offset += chan->gm_rpn_fine_tuning / 24; 838 839#ifdef SNDRV_EMUX_USE_RAW_EFFECT 840 /* add initial pitch correction */ 841 if (chan->private) { 842 snd_emux_effect_table_t *fx = chan->private; 843 if (fx->flag[EMUX_FX_INIT_PITCH]) 844 offset += fx->val[EMUX_FX_INIT_PITCH]; 845 } 846#endif 847 848 /* 0xe000: root pitch */ 849 offset += 0xe000 + vp->reg.rate_offset; 850 offset += vp->emu->pitch_shift; 851 LIMITVALUE(offset, 0, 0xffff); 852 if (offset == vp->apitch) 853 return 0; /* unchanged */ 854 vp->apitch = offset; 855 return 1; /* value changed */ 856} 857 858/* 859 * Get the bank number assigned to the channel 860 */ 861static int 862get_bank(snd_emux_port_t *port, snd_midi_channel_t *chan) 863{ 864 int val; 865 866 switch (port->chset.midi_mode) { 867 case SNDRV_MIDI_MODE_XG: 868 val = chan->control[MIDI_CTL_MSB_BANK]; 869 if (val == 127) 870 return 128; /* return drum bank */ 871 return chan->control[MIDI_CTL_LSB_BANK]; 872 873 case SNDRV_MIDI_MODE_GS: 874 if (chan->drum_channel) 875 return 128; 876 /* ignore LSB (bank map) */ 877 return chan->control[MIDI_CTL_MSB_BANK]; 878 879 default: 880 if (chan->drum_channel) 881 return 128; 882 return chan->control[MIDI_CTL_MSB_BANK]; 883 } 884} 885 886 887/* Look for the zones matching with the given note and velocity. 888 * The resultant zones are stored on table. 889 */ 890static int 891get_zone(snd_emux_t *emu, snd_emux_port_t *port, 892 int *notep, int vel, snd_midi_channel_t *chan, snd_sf_zone_t **table) 893{ 894 int preset, bank, def_preset, def_bank; 895 896 bank = get_bank(port, chan); 897 preset = chan->midi_program; 898 899 if (SF_IS_DRUM_BANK(bank)) { 900 def_preset = port->ctrls[EMUX_MD_DEF_DRUM]; 901 def_bank = bank; 902 } else { 903 def_preset = preset; 904 def_bank = port->ctrls[EMUX_MD_DEF_BANK]; 905 } 906 907 return snd_soundfont_search_zone(emu->sflist, notep, vel, preset, bank, 908 def_preset, def_bank, 909 table, SNDRV_EMUX_MAX_MULTI_VOICES); 910} 911 912/* 913 */ 914void 915snd_emux_init_voices(snd_emux_t *emu) 916{ 917 snd_emux_voice_t *vp; 918 int i; 919 unsigned long flags; 920 921 spin_lock_irqsave(&emu->voice_lock, flags); 922 for (i = 0; i < emu->max_voices; i++) { 923 vp = &emu->voices[i]; 924 vp->ch = -1; /* not used */ 925 vp->state = SNDRV_EMUX_ST_OFF; 926 vp->chan = NULL; 927 vp->port = NULL; 928 vp->time = 0; 929 vp->emu = emu; 930 vp->hw = emu->hw; 931 } 932 spin_unlock_irqrestore(&emu->voice_lock, flags); 933} 934 935/* 936 */ 937void snd_emux_lock_voice(snd_emux_t *emu, int voice) 938{ 939 unsigned long flags; 940 941 spin_lock_irqsave(&emu->voice_lock, flags); 942 if (emu->voices[voice].state == SNDRV_EMUX_ST_OFF) 943 emu->voices[voice].state = SNDRV_EMUX_ST_LOCKED; 944 else 945 snd_printk("invalid voice for lock %d (state = %x)\n", 946 voice, emu->voices[voice].state); 947 spin_unlock_irqrestore(&emu->voice_lock, flags); 948} 949 950/* 951 */ 952void snd_emux_unlock_voice(snd_emux_t *emu, int voice) 953{ 954 unsigned long flags; 955 956 spin_lock_irqsave(&emu->voice_lock, flags); 957 if (emu->voices[voice].state == SNDRV_EMUX_ST_LOCKED) 958 emu->voices[voice].state = SNDRV_EMUX_ST_OFF; 959 else 960 snd_printk("invalid voice for unlock %d (state = %x)\n", 961 voice, emu->voices[voice].state); 962 spin_unlock_irqrestore(&emu->voice_lock, flags); 963} 964