root/sound/synth/emux/emux_synth.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. snd_emux_note_on
  2. snd_emux_note_off
  3. snd_emux_timer_callback
  4. snd_emux_key_press
  5. snd_emux_update_channel
  6. snd_emux_update_port
  7. snd_emux_control
  8. terminate_note1
  9. snd_emux_terminate_note
  10. snd_emux_terminate_all
  11. snd_emux_sounds_off_all
  12. exclusive_note_off
  13. terminate_voice
  14. update_voice
  15. setup_voice
  16. calc_pan
  17. calc_volume
  18. calc_pitch
  19. get_bank
  20. get_zone
  21. snd_emux_init_voices
  22. snd_emux_lock_voice
  23. snd_emux_unlock_voice

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

/* [<][>][^][v][top][bottom][index][help] */