Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  *  Midi synth routines for the Emu8k/Emu10k1
0004  *
0005  *  Copyright (C) 1999 Steve Ratcliffe
0006  *  Copyright (c) 1999-2000 Takashi Iwai <tiwai@suse.de>
0007  *
0008  *  Contains code based on awe_wave.c by Takashi Iwai
0009  */
0010 
0011 #include <linux/export.h>
0012 #include "emux_voice.h"
0013 #include <sound/asoundef.h>
0014 
0015 /*
0016  * Prototypes
0017  */
0018 
0019 /*
0020  * Ensure a value is between two points
0021  * macro evaluates its args more than once, so changed to upper-case.
0022  */
0023 #define LIMITVALUE(x, a, b) do { if ((x) < (a)) (x) = (a); else if ((x) > (b)) (x) = (b); } while (0)
0024 #define LIMITMAX(x, a) do {if ((x) > (a)) (x) = (a); } while (0)
0025 
0026 static int get_zone(struct snd_emux *emu, struct snd_emux_port *port,
0027             int *notep, int vel, struct snd_midi_channel *chan,
0028             struct snd_sf_zone **table);
0029 static int get_bank(struct snd_emux_port *port, struct snd_midi_channel *chan);
0030 static void terminate_note1(struct snd_emux *emu, int note,
0031                 struct snd_midi_channel *chan, int free);
0032 static void exclusive_note_off(struct snd_emux *emu, struct snd_emux_port *port,
0033                    int exclass);
0034 static void terminate_voice(struct snd_emux *emu, struct snd_emux_voice *vp, int free);
0035 static void update_voice(struct snd_emux *emu, struct snd_emux_voice *vp, int update);
0036 static void setup_voice(struct snd_emux_voice *vp);
0037 static int calc_pan(struct snd_emux_voice *vp);
0038 static int calc_volume(struct snd_emux_voice *vp);
0039 static int calc_pitch(struct snd_emux_voice *vp);
0040 
0041 
0042 /*
0043  * Start a note.
0044  */
0045 void
0046 snd_emux_note_on(void *p, int note, int vel, struct snd_midi_channel *chan)
0047 {
0048     struct snd_emux *emu;
0049     int i, key, nvoices;
0050     struct snd_emux_voice *vp;
0051     struct snd_sf_zone *table[SNDRV_EMUX_MAX_MULTI_VOICES];
0052     unsigned long flags;
0053     struct snd_emux_port *port;
0054 
0055     port = p;
0056     if (snd_BUG_ON(!port || !chan))
0057         return;
0058 
0059     emu = port->emu;
0060     if (snd_BUG_ON(!emu || !emu->ops.get_voice || !emu->ops.trigger))
0061         return;
0062 
0063     key = note; /* remember the original note */
0064     nvoices = get_zone(emu, port, &note, vel, chan, table);
0065     if (! nvoices)
0066         return;
0067 
0068     /* exclusive note off */
0069     for (i = 0; i < nvoices; i++) {
0070         struct snd_sf_zone *zp = table[i];
0071         if (zp && zp->v.exclusiveClass)
0072             exclusive_note_off(emu, port, zp->v.exclusiveClass);
0073     }
0074 
0075 #if 0 // seems not necessary
0076     /* Turn off the same note on the same channel. */
0077     terminate_note1(emu, key, chan, 0);
0078 #endif
0079 
0080     spin_lock_irqsave(&emu->voice_lock, flags);
0081     for (i = 0; i < nvoices; i++) {
0082 
0083         /* set up each voice parameter */
0084         /* at this stage, we don't trigger the voice yet. */
0085 
0086         if (table[i] == NULL)
0087             continue;
0088 
0089         vp = emu->ops.get_voice(emu, port);
0090         if (vp == NULL || vp->ch < 0)
0091             continue;
0092         if (STATE_IS_PLAYING(vp->state))
0093             emu->ops.terminate(vp);
0094 
0095         vp->time = emu->use_time++;
0096         vp->chan = chan;
0097         vp->port = port;
0098         vp->key = key;
0099         vp->note = note;
0100         vp->velocity = vel;
0101         vp->zone = table[i];
0102         if (vp->zone->sample)
0103             vp->block = vp->zone->sample->block;
0104         else
0105             vp->block = NULL;
0106 
0107         setup_voice(vp);
0108 
0109         vp->state = SNDRV_EMUX_ST_STANDBY;
0110         if (emu->ops.prepare) {
0111             vp->state = SNDRV_EMUX_ST_OFF;
0112             if (emu->ops.prepare(vp) >= 0)
0113                 vp->state = SNDRV_EMUX_ST_STANDBY;
0114         }
0115     }
0116 
0117     /* start envelope now */
0118     for (i = 0; i < emu->max_voices; i++) {
0119         vp = &emu->voices[i];
0120         if (vp->state == SNDRV_EMUX_ST_STANDBY &&
0121             vp->chan == chan) {
0122             emu->ops.trigger(vp);
0123             vp->state = SNDRV_EMUX_ST_ON;
0124             vp->ontime = jiffies; /* remember the trigger timing */
0125         }
0126     }
0127     spin_unlock_irqrestore(&emu->voice_lock, flags);
0128 
0129 #ifdef SNDRV_EMUX_USE_RAW_EFFECT
0130     if (port->port_mode == SNDRV_EMUX_PORT_MODE_OSS_SYNTH) {
0131         /* clear voice position for the next note on this channel */
0132         struct snd_emux_effect_table *fx = chan->private;
0133         if (fx) {
0134             fx->flag[EMUX_FX_SAMPLE_START] = 0;
0135             fx->flag[EMUX_FX_COARSE_SAMPLE_START] = 0;
0136         }
0137     }
0138 #endif
0139 }
0140 
0141 /*
0142  * Release a note in response to a midi note off.
0143  */
0144 void
0145 snd_emux_note_off(void *p, int note, int vel, struct snd_midi_channel *chan)
0146 {
0147     int ch;
0148     struct snd_emux *emu;
0149     struct snd_emux_voice *vp;
0150     unsigned long flags;
0151     struct snd_emux_port *port;
0152 
0153     port = p;
0154     if (snd_BUG_ON(!port || !chan))
0155         return;
0156 
0157     emu = port->emu;
0158     if (snd_BUG_ON(!emu || !emu->ops.release))
0159         return;
0160 
0161     spin_lock_irqsave(&emu->voice_lock, flags);
0162     for (ch = 0; ch < emu->max_voices; ch++) {
0163         vp = &emu->voices[ch];
0164         if (STATE_IS_PLAYING(vp->state) &&
0165             vp->chan == chan && vp->key == note) {
0166             vp->state = SNDRV_EMUX_ST_RELEASED;
0167             if (vp->ontime == jiffies) {
0168                 /* if note-off is sent too shortly after
0169                  * note-on, emuX engine cannot produce the sound
0170                  * correctly.  so we'll release this note
0171                  * a bit later via timer callback.
0172                  */
0173                 vp->state = SNDRV_EMUX_ST_PENDING;
0174                 if (! emu->timer_active) {
0175                     mod_timer(&emu->tlist, jiffies + 1);
0176                     emu->timer_active = 1;
0177                 }
0178             } else
0179                 /* ok now release the note */
0180                 emu->ops.release(vp);
0181         }
0182     }
0183     spin_unlock_irqrestore(&emu->voice_lock, flags);
0184 }
0185 
0186 /*
0187  * timer callback
0188  *
0189  * release the pending note-offs
0190  */
0191 void snd_emux_timer_callback(struct timer_list *t)
0192 {
0193     struct snd_emux *emu = from_timer(emu, t, tlist);
0194     struct snd_emux_voice *vp;
0195     unsigned long flags;
0196     int ch, do_again = 0;
0197 
0198     spin_lock_irqsave(&emu->voice_lock, flags);
0199     for (ch = 0; ch < emu->max_voices; ch++) {
0200         vp = &emu->voices[ch];
0201         if (vp->state == SNDRV_EMUX_ST_PENDING) {
0202             if (vp->ontime == jiffies)
0203                 do_again++; /* release this at the next interrupt */
0204             else {
0205                 emu->ops.release(vp);
0206                 vp->state = SNDRV_EMUX_ST_RELEASED;
0207             }
0208         }
0209     }
0210     if (do_again) {
0211         mod_timer(&emu->tlist, jiffies + 1);
0212         emu->timer_active = 1;
0213     } else
0214         emu->timer_active = 0;
0215     spin_unlock_irqrestore(&emu->voice_lock, flags);
0216 }
0217 
0218 /*
0219  * key pressure change
0220  */
0221 void
0222 snd_emux_key_press(void *p, int note, int vel, struct snd_midi_channel *chan)
0223 {
0224     int ch;
0225     struct snd_emux *emu;
0226     struct snd_emux_voice *vp;
0227     unsigned long flags;
0228     struct snd_emux_port *port;
0229 
0230     port = p;
0231     if (snd_BUG_ON(!port || !chan))
0232         return;
0233 
0234     emu = port->emu;
0235     if (snd_BUG_ON(!emu || !emu->ops.update))
0236         return;
0237 
0238     spin_lock_irqsave(&emu->voice_lock, flags);
0239     for (ch = 0; ch < emu->max_voices; ch++) {
0240         vp = &emu->voices[ch];
0241         if (vp->state == SNDRV_EMUX_ST_ON &&
0242             vp->chan == chan && vp->key == note) {
0243             vp->velocity = vel;
0244             update_voice(emu, vp, SNDRV_EMUX_UPDATE_VOLUME);
0245         }
0246     }
0247     spin_unlock_irqrestore(&emu->voice_lock, flags);
0248 }
0249 
0250 
0251 /*
0252  * Modulate the voices which belong to the channel
0253  */
0254 void
0255 snd_emux_update_channel(struct snd_emux_port *port, struct snd_midi_channel *chan, int update)
0256 {
0257     struct snd_emux *emu;
0258     struct snd_emux_voice *vp;
0259     int i;
0260     unsigned long flags;
0261 
0262     if (! update)
0263         return;
0264 
0265     emu = port->emu;
0266     if (snd_BUG_ON(!emu || !emu->ops.update))
0267         return;
0268 
0269     spin_lock_irqsave(&emu->voice_lock, flags);
0270     for (i = 0; i < emu->max_voices; i++) {
0271         vp = &emu->voices[i];
0272         if (vp->chan == chan)
0273             update_voice(emu, vp, update);
0274     }
0275     spin_unlock_irqrestore(&emu->voice_lock, flags);
0276 }
0277 
0278 /*
0279  * Modulate all the voices which belong to the port.
0280  */
0281 void
0282 snd_emux_update_port(struct snd_emux_port *port, int update)
0283 {
0284     struct snd_emux *emu; 
0285     struct snd_emux_voice *vp;
0286     int i;
0287     unsigned long flags;
0288 
0289     if (! update)
0290         return;
0291 
0292     emu = port->emu;
0293     if (snd_BUG_ON(!emu || !emu->ops.update))
0294         return;
0295 
0296     spin_lock_irqsave(&emu->voice_lock, flags);
0297     for (i = 0; i < emu->max_voices; i++) {
0298         vp = &emu->voices[i];
0299         if (vp->port == port)
0300             update_voice(emu, vp, update);
0301     }
0302     spin_unlock_irqrestore(&emu->voice_lock, flags);
0303 }
0304 
0305 
0306 /*
0307  * Deal with a controller type event.  This includes all types of
0308  * control events, not just the midi controllers
0309  */
0310 void
0311 snd_emux_control(void *p, int type, struct snd_midi_channel *chan)
0312 {
0313     struct snd_emux_port *port;
0314 
0315     port = p;
0316     if (snd_BUG_ON(!port || !chan))
0317         return;
0318 
0319     switch (type) {
0320     case MIDI_CTL_MSB_MAIN_VOLUME:
0321     case MIDI_CTL_MSB_EXPRESSION:
0322         snd_emux_update_channel(port, chan, SNDRV_EMUX_UPDATE_VOLUME);
0323         break;
0324         
0325     case MIDI_CTL_MSB_PAN:
0326         snd_emux_update_channel(port, chan, SNDRV_EMUX_UPDATE_PAN);
0327         break;
0328 
0329     case MIDI_CTL_SOFT_PEDAL:
0330 #ifdef SNDRV_EMUX_USE_RAW_EFFECT
0331         /* FIXME: this is an emulation */
0332         if (chan->control[type] >= 64)
0333             snd_emux_send_effect(port, chan, EMUX_FX_CUTOFF, -160,
0334                      EMUX_FX_FLAG_ADD);
0335         else
0336             snd_emux_send_effect(port, chan, EMUX_FX_CUTOFF, 0,
0337                      EMUX_FX_FLAG_OFF);
0338 #endif
0339         break;
0340 
0341     case MIDI_CTL_PITCHBEND:
0342         snd_emux_update_channel(port, chan, SNDRV_EMUX_UPDATE_PITCH);
0343         break;
0344 
0345     case MIDI_CTL_MSB_MODWHEEL:
0346     case MIDI_CTL_CHAN_PRESSURE:
0347         snd_emux_update_channel(port, chan,
0348                     SNDRV_EMUX_UPDATE_FMMOD |
0349                     SNDRV_EMUX_UPDATE_FM2FRQ2);
0350         break;
0351 
0352     }
0353 
0354     if (port->chset.midi_mode == SNDRV_MIDI_MODE_XG) {
0355         snd_emux_xg_control(port, chan, type);
0356     }
0357 }
0358 
0359 
0360 /*
0361  * terminate note - if free flag is true, free the terminated voice
0362  */
0363 static void
0364 terminate_note1(struct snd_emux *emu, int note, struct snd_midi_channel *chan, int free)
0365 {
0366     int  i;
0367     struct snd_emux_voice *vp;
0368     unsigned long flags;
0369 
0370     spin_lock_irqsave(&emu->voice_lock, flags);
0371     for (i = 0; i < emu->max_voices; i++) {
0372         vp = &emu->voices[i];
0373         if (STATE_IS_PLAYING(vp->state) && vp->chan == chan &&
0374             vp->key == note)
0375             terminate_voice(emu, vp, free);
0376     }
0377     spin_unlock_irqrestore(&emu->voice_lock, flags);
0378 }
0379 
0380 
0381 /*
0382  * terminate note - exported for midi emulation
0383  */
0384 void
0385 snd_emux_terminate_note(void *p, int note, struct snd_midi_channel *chan)
0386 {
0387     struct snd_emux *emu;
0388     struct snd_emux_port *port;
0389 
0390     port = p;
0391     if (snd_BUG_ON(!port || !chan))
0392         return;
0393 
0394     emu = port->emu;
0395     if (snd_BUG_ON(!emu || !emu->ops.terminate))
0396         return;
0397 
0398     terminate_note1(emu, note, chan, 1);
0399 }
0400 
0401 
0402 /*
0403  * Terminate all the notes
0404  */
0405 void
0406 snd_emux_terminate_all(struct snd_emux *emu)
0407 {
0408     int i;
0409     struct snd_emux_voice *vp;
0410     unsigned long flags;
0411 
0412     spin_lock_irqsave(&emu->voice_lock, flags);
0413     for (i = 0; i < emu->max_voices; i++) {
0414         vp = &emu->voices[i];
0415         if (STATE_IS_PLAYING(vp->state))
0416             terminate_voice(emu, vp, 0);
0417         if (vp->state == SNDRV_EMUX_ST_OFF) {
0418             if (emu->ops.free_voice)
0419                 emu->ops.free_voice(vp);
0420             if (emu->ops.reset)
0421                 emu->ops.reset(emu, i);
0422         }
0423         vp->time = 0;
0424     }
0425     /* initialize allocation time */
0426     emu->use_time = 0;
0427     spin_unlock_irqrestore(&emu->voice_lock, flags);
0428 }
0429 
0430 EXPORT_SYMBOL(snd_emux_terminate_all);
0431 
0432 /*
0433  * Terminate all voices associated with the given port
0434  */
0435 void
0436 snd_emux_sounds_off_all(struct snd_emux_port *port)
0437 {
0438     int i;
0439     struct snd_emux *emu;
0440     struct snd_emux_voice *vp;
0441     unsigned long flags;
0442 
0443     if (snd_BUG_ON(!port))
0444         return;
0445     emu = port->emu;
0446     if (snd_BUG_ON(!emu || !emu->ops.terminate))
0447         return;
0448 
0449     spin_lock_irqsave(&emu->voice_lock, flags);
0450     for (i = 0; i < emu->max_voices; i++) {
0451         vp = &emu->voices[i];
0452         if (STATE_IS_PLAYING(vp->state) &&
0453             vp->port == port)
0454             terminate_voice(emu, vp, 0);
0455         if (vp->state == SNDRV_EMUX_ST_OFF) {
0456             if (emu->ops.free_voice)
0457                 emu->ops.free_voice(vp);
0458             if (emu->ops.reset)
0459                 emu->ops.reset(emu, i);
0460         }
0461     }
0462     spin_unlock_irqrestore(&emu->voice_lock, flags);
0463 }
0464 
0465 
0466 /*
0467  * Terminate all voices that have the same exclusive class.  This
0468  * is mainly for drums.
0469  */
0470 static void
0471 exclusive_note_off(struct snd_emux *emu, struct snd_emux_port *port, int exclass)
0472 {
0473     struct snd_emux_voice *vp;
0474     int  i;
0475     unsigned long flags;
0476 
0477     spin_lock_irqsave(&emu->voice_lock, flags);
0478     for (i = 0; i < emu->max_voices; i++) {
0479         vp = &emu->voices[i];
0480         if (STATE_IS_PLAYING(vp->state) && vp->port == port &&
0481             vp->reg.exclusiveClass == exclass) {
0482             terminate_voice(emu, vp, 0);
0483         }
0484     }
0485     spin_unlock_irqrestore(&emu->voice_lock, flags);
0486 }
0487 
0488 /*
0489  * terminate a voice
0490  * if free flag is true, call free_voice after termination
0491  */
0492 static void
0493 terminate_voice(struct snd_emux *emu, struct snd_emux_voice *vp, int free)
0494 {
0495     emu->ops.terminate(vp);
0496     vp->time = emu->use_time++;
0497     vp->chan = NULL;
0498     vp->port = NULL;
0499     vp->zone = NULL;
0500     vp->block = NULL;
0501     vp->state = SNDRV_EMUX_ST_OFF;
0502     if (free && emu->ops.free_voice)
0503         emu->ops.free_voice(vp);
0504 }
0505 
0506 
0507 /*
0508  * Modulate the voice
0509  */
0510 static void
0511 update_voice(struct snd_emux *emu, struct snd_emux_voice *vp, int update)
0512 {
0513     if (!STATE_IS_PLAYING(vp->state))
0514         return;
0515 
0516     if (vp->chan == NULL || vp->port == NULL)
0517         return;
0518     if (update & SNDRV_EMUX_UPDATE_VOLUME)
0519         calc_volume(vp);
0520     if (update & SNDRV_EMUX_UPDATE_PITCH)
0521         calc_pitch(vp);
0522     if (update & SNDRV_EMUX_UPDATE_PAN) {
0523         if (! calc_pan(vp) && (update == SNDRV_EMUX_UPDATE_PAN))
0524             return;
0525     }
0526     emu->ops.update(vp, update);
0527 }
0528 
0529 
0530 #if 0 // not used
0531 /* table for volume target calculation */
0532 static const unsigned short voltarget[16] = {
0533     0xEAC0, 0xE0C8, 0xD740, 0xCE20, 0xC560, 0xBD08, 0xB500, 0xAD58,
0534     0xA5F8, 0x9EF0, 0x9830, 0x91C0, 0x8B90, 0x85A8, 0x8000, 0x7A90
0535 };
0536 #endif
0537 
0538 #define LO_BYTE(v)  ((v) & 0xff)
0539 #define HI_BYTE(v)  (((v) >> 8) & 0xff)
0540 
0541 /*
0542  * Sets up the voice structure by calculating some values that
0543  * will be needed later.
0544  */
0545 static void
0546 setup_voice(struct snd_emux_voice *vp)
0547 {
0548     struct soundfont_voice_parm *parm;
0549     int pitch;
0550 
0551     /* copy the original register values */
0552     vp->reg = vp->zone->v;
0553 
0554 #ifdef SNDRV_EMUX_USE_RAW_EFFECT
0555     snd_emux_setup_effect(vp);
0556 #endif
0557 
0558     /* reset status */
0559     vp->apan = -1;
0560     vp->avol = -1;
0561     vp->apitch = -1;
0562 
0563     calc_volume(vp);
0564     calc_pitch(vp);
0565     calc_pan(vp);
0566 
0567     parm = &vp->reg.parm;
0568 
0569     /* compute filter target and correct modulation parameters */
0570     if (LO_BYTE(parm->modatkhld) >= 0x80 && parm->moddelay >= 0x8000) {
0571         parm->moddelay = 0xbfff;
0572         pitch = (HI_BYTE(parm->pefe) << 4) + vp->apitch;
0573         if (pitch > 0xffff)
0574             pitch = 0xffff;
0575         /* calculate filter target */
0576         vp->ftarget = parm->cutoff + LO_BYTE(parm->pefe);
0577         LIMITVALUE(vp->ftarget, 0, 255);
0578         vp->ftarget <<= 8;
0579     } else {
0580         vp->ftarget = parm->cutoff;
0581         vp->ftarget <<= 8;
0582         pitch = vp->apitch;
0583     }
0584 
0585     /* compute pitch target */
0586     if (pitch != 0xffff) {
0587         vp->ptarget = 1 << (pitch >> 12);
0588         if (pitch & 0x800) vp->ptarget += (vp->ptarget*0x102e)/0x2710;
0589         if (pitch & 0x400) vp->ptarget += (vp->ptarget*0x764)/0x2710;
0590         if (pitch & 0x200) vp->ptarget += (vp->ptarget*0x389)/0x2710;
0591         vp->ptarget += (vp->ptarget >> 1);
0592         if (vp->ptarget > 0xffff) vp->ptarget = 0xffff;
0593     } else
0594         vp->ptarget = 0xffff;
0595 
0596     if (LO_BYTE(parm->modatkhld) >= 0x80) {
0597         parm->modatkhld &= ~0xff;
0598         parm->modatkhld |= 0x7f;
0599     }
0600 
0601     /* compute volume target and correct volume parameters */
0602     vp->vtarget = 0;
0603 #if 0 /* FIXME: this leads to some clicks.. */
0604     if (LO_BYTE(parm->volatkhld) >= 0x80 && parm->voldelay >= 0x8000) {
0605         parm->voldelay = 0xbfff;
0606         vp->vtarget = voltarget[vp->avol % 0x10] >> (vp->avol >> 4);
0607     }
0608 #endif
0609 
0610     if (LO_BYTE(parm->volatkhld) >= 0x80) {
0611         parm->volatkhld &= ~0xff;
0612         parm->volatkhld |= 0x7f;
0613     }
0614 }
0615 
0616 /*
0617  * calculate pitch parameter
0618  */
0619 static const unsigned char pan_volumes[256] = {
0620 0x00,0x03,0x06,0x09,0x0c,0x0f,0x12,0x14,0x17,0x1a,0x1d,0x20,0x22,0x25,0x28,0x2a,
0621 0x2d,0x30,0x32,0x35,0x37,0x3a,0x3c,0x3f,0x41,0x44,0x46,0x49,0x4b,0x4d,0x50,0x52,
0622 0x54,0x57,0x59,0x5b,0x5d,0x60,0x62,0x64,0x66,0x68,0x6a,0x6c,0x6f,0x71,0x73,0x75,
0623 0x77,0x79,0x7b,0x7c,0x7e,0x80,0x82,0x84,0x86,0x88,0x89,0x8b,0x8d,0x8f,0x90,0x92,
0624 0x94,0x96,0x97,0x99,0x9a,0x9c,0x9e,0x9f,0xa1,0xa2,0xa4,0xa5,0xa7,0xa8,0xaa,0xab,
0625 0xad,0xae,0xaf,0xb1,0xb2,0xb3,0xb5,0xb6,0xb7,0xb9,0xba,0xbb,0xbc,0xbe,0xbf,0xc0,
0626 0xc1,0xc2,0xc3,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xcb,0xcc,0xcd,0xce,0xcf,0xd0,0xd1,
0627 0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd7,0xd8,0xd9,0xda,0xdb,0xdc,0xdc,0xdd,0xde,0xdf,
0628 0xdf,0xe0,0xe1,0xe2,0xe2,0xe3,0xe4,0xe4,0xe5,0xe6,0xe6,0xe7,0xe8,0xe8,0xe9,0xe9,
0629 0xea,0xeb,0xeb,0xec,0xec,0xed,0xed,0xee,0xee,0xef,0xef,0xf0,0xf0,0xf1,0xf1,0xf1,
0630 0xf2,0xf2,0xf3,0xf3,0xf3,0xf4,0xf4,0xf5,0xf5,0xf5,0xf6,0xf6,0xf6,0xf7,0xf7,0xf7,
0631 0xf7,0xf8,0xf8,0xf8,0xf9,0xf9,0xf9,0xf9,0xf9,0xfa,0xfa,0xfa,0xfa,0xfb,0xfb,0xfb,
0632 0xfb,0xfb,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,
0633 0xfd,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,
0634 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0635 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0636 };
0637 
0638 static int
0639 calc_pan(struct snd_emux_voice *vp)
0640 {
0641     struct snd_midi_channel *chan = vp->chan;
0642     int pan;
0643 
0644     /* pan & loop start (pan 8bit, MSB, 0:right, 0xff:left) */
0645     if (vp->reg.fixpan > 0) /* 0-127 */
0646         pan = 255 - (int)vp->reg.fixpan * 2;
0647     else {
0648         pan = chan->control[MIDI_CTL_MSB_PAN] - 64;
0649         if (vp->reg.pan >= 0) /* 0-127 */
0650             pan += vp->reg.pan - 64;
0651         pan = 127 - (int)pan * 2;
0652     }
0653     LIMITVALUE(pan, 0, 255);
0654 
0655     if (vp->emu->linear_panning) {
0656         /* assuming linear volume */
0657         if (pan != vp->apan) {
0658             vp->apan = pan;
0659             if (pan == 0)
0660                 vp->aaux = 0xff;
0661             else
0662                 vp->aaux = (-pan) & 0xff;
0663             return 1;
0664         } else
0665             return 0;
0666     } else {
0667         /* using volume table */
0668         if (vp->apan != (int)pan_volumes[pan]) {
0669             vp->apan = pan_volumes[pan];
0670             vp->aaux = pan_volumes[255 - pan];
0671             return 1;
0672         }
0673         return 0;
0674     }
0675 }
0676 
0677 
0678 /*
0679  * calculate volume attenuation
0680  *
0681  * Voice volume is controlled by volume attenuation parameter.
0682  * So volume becomes maximum when avol is 0 (no attenuation), and
0683  * minimum when 255 (-96dB or silence).
0684  */
0685 
0686 /* tables for volume->attenuation calculation */
0687 static const unsigned char voltab1[128] = {
0688    0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
0689    0x63, 0x2b, 0x29, 0x28, 0x27, 0x26, 0x25, 0x24, 0x23, 0x22,
0690    0x21, 0x20, 0x1f, 0x1e, 0x1e, 0x1d, 0x1c, 0x1b, 0x1b, 0x1a,
0691    0x19, 0x19, 0x18, 0x17, 0x17, 0x16, 0x16, 0x15, 0x15, 0x14,
0692    0x14, 0x13, 0x13, 0x13, 0x12, 0x12, 0x11, 0x11, 0x11, 0x10,
0693    0x10, 0x10, 0x0f, 0x0f, 0x0f, 0x0e, 0x0e, 0x0e, 0x0e, 0x0d,
0694    0x0d, 0x0d, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0b, 0x0b, 0x0b,
0695    0x0b, 0x0a, 0x0a, 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09,
0696    0x08, 0x08, 0x08, 0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x06,
0697    0x06, 0x06, 0x06, 0x06, 0x05, 0x05, 0x05, 0x05, 0x05, 0x04,
0698    0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02,
0699    0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01,
0700    0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
0701 };
0702 
0703 static const unsigned char voltab2[128] = {
0704    0x32, 0x31, 0x30, 0x2f, 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x2a,
0705    0x29, 0x28, 0x27, 0x26, 0x25, 0x24, 0x24, 0x23, 0x22, 0x21,
0706    0x21, 0x20, 0x1f, 0x1e, 0x1e, 0x1d, 0x1c, 0x1c, 0x1b, 0x1a,
0707    0x1a, 0x19, 0x19, 0x18, 0x18, 0x17, 0x16, 0x16, 0x15, 0x15,
0708    0x14, 0x14, 0x13, 0x13, 0x13, 0x12, 0x12, 0x11, 0x11, 0x10,
0709    0x10, 0x10, 0x0f, 0x0f, 0x0f, 0x0e, 0x0e, 0x0e, 0x0d, 0x0d,
0710    0x0d, 0x0c, 0x0c, 0x0c, 0x0b, 0x0b, 0x0b, 0x0b, 0x0a, 0x0a,
0711    0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x08, 0x08, 0x08,
0712    0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x07, 0x06, 0x06, 0x06,
0713    0x06, 0x06, 0x06, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
0714    0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03,
0715    0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01,
0716    0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00
0717 };
0718 
0719 static const unsigned char expressiontab[128] = {
0720    0x7f, 0x6c, 0x62, 0x5a, 0x54, 0x50, 0x4b, 0x48, 0x45, 0x42,
0721    0x40, 0x3d, 0x3b, 0x39, 0x38, 0x36, 0x34, 0x33, 0x31, 0x30,
0722    0x2f, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, 0x27, 0x26, 0x25,
0723    0x24, 0x24, 0x23, 0x22, 0x21, 0x21, 0x20, 0x1f, 0x1e, 0x1e,
0724    0x1d, 0x1d, 0x1c, 0x1b, 0x1b, 0x1a, 0x1a, 0x19, 0x18, 0x18,
0725    0x17, 0x17, 0x16, 0x16, 0x15, 0x15, 0x15, 0x14, 0x14, 0x13,
0726    0x13, 0x12, 0x12, 0x11, 0x11, 0x11, 0x10, 0x10, 0x0f, 0x0f,
0727    0x0f, 0x0e, 0x0e, 0x0e, 0x0d, 0x0d, 0x0d, 0x0c, 0x0c, 0x0c,
0728    0x0b, 0x0b, 0x0b, 0x0a, 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09,
0729    0x08, 0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x06, 0x06, 0x06,
0730    0x06, 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03,
0731    0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01,
0732    0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
0733 };
0734 
0735 /*
0736  * Magic to calculate the volume (actually attenuation) from all the
0737  * voice and channels parameters.
0738  */
0739 static int
0740 calc_volume(struct snd_emux_voice *vp)
0741 {
0742     int vol;
0743     int main_vol, expression_vol, master_vol;
0744     struct snd_midi_channel *chan = vp->chan;
0745     struct snd_emux_port *port = vp->port;
0746 
0747     expression_vol = chan->control[MIDI_CTL_MSB_EXPRESSION];
0748     LIMITMAX(vp->velocity, 127);
0749     LIMITVALUE(expression_vol, 0, 127);
0750     if (port->port_mode == SNDRV_EMUX_PORT_MODE_OSS_SYNTH) {
0751         /* 0 - 127 */
0752         main_vol = chan->control[MIDI_CTL_MSB_MAIN_VOLUME];
0753         vol = (vp->velocity * main_vol * expression_vol) / (127*127);
0754         vol = vol * vp->reg.amplitude / 127;
0755 
0756         LIMITVALUE(vol, 0, 127);
0757 
0758         /* calc to attenuation */
0759         vol = snd_sf_vol_table[vol];
0760 
0761     } else {
0762         main_vol = chan->control[MIDI_CTL_MSB_MAIN_VOLUME] * vp->reg.amplitude / 127;
0763         LIMITVALUE(main_vol, 0, 127);
0764 
0765         vol = voltab1[main_vol] + voltab2[vp->velocity];
0766         vol = (vol * 8) / 3;
0767         vol += vp->reg.attenuation;
0768         vol += ((0x100 - vol) * expressiontab[expression_vol])/128;
0769     }
0770 
0771     master_vol = port->chset.gs_master_volume;
0772     LIMITVALUE(master_vol, 0, 127);
0773     vol += snd_sf_vol_table[master_vol];
0774     vol += port->volume_atten;
0775 
0776 #ifdef SNDRV_EMUX_USE_RAW_EFFECT
0777     if (chan->private) {
0778         struct snd_emux_effect_table *fx = chan->private;
0779         vol += fx->val[EMUX_FX_ATTEN];
0780     }
0781 #endif
0782 
0783     LIMITVALUE(vol, 0, 255);
0784     if (vp->avol == vol)
0785         return 0; /* value unchanged */
0786 
0787     vp->avol = vol;
0788     if (!SF_IS_DRUM_BANK(get_bank(port, chan))
0789         && LO_BYTE(vp->reg.parm.volatkhld) < 0x7d) {
0790         int atten;
0791         if (vp->velocity < 70)
0792             atten = 70;
0793         else
0794             atten = vp->velocity;
0795         vp->acutoff = (atten * vp->reg.parm.cutoff + 0xa0) >> 7;
0796     } else {
0797         vp->acutoff = vp->reg.parm.cutoff;
0798     }
0799 
0800     return 1; /* value changed */
0801 }
0802 
0803 /*
0804  * calculate pitch offset
0805  *
0806  * 0xE000 is no pitch offset at 44100Hz sample.
0807  * Every 4096 is one octave.
0808  */
0809 
0810 static int
0811 calc_pitch(struct snd_emux_voice *vp)
0812 {
0813     struct snd_midi_channel *chan = vp->chan;
0814     int offset;
0815 
0816     /* calculate offset */
0817     if (vp->reg.fixkey >= 0) {
0818         offset = (vp->reg.fixkey - vp->reg.root) * 4096 / 12;
0819     } else {
0820         offset = (vp->note - vp->reg.root) * 4096 / 12;
0821     }
0822     offset = (offset * vp->reg.scaleTuning) / 100;
0823     offset += vp->reg.tune * 4096 / 1200;
0824     if (chan->midi_pitchbend != 0) {
0825         /* (128 * 8192: 1 semitone) ==> (4096: 12 semitones) */
0826         offset += chan->midi_pitchbend * chan->gm_rpn_pitch_bend_range / 3072;
0827     }
0828 
0829     /* tuning via RPN:
0830      *   coarse = -8192 to 8192 (100 cent per 128)
0831      *   fine = -8192 to 8192 (max=100cent)
0832      */
0833     /* 4096 = 1200 cents in emu8000 parameter */
0834     offset += chan->gm_rpn_coarse_tuning * 4096 / (12 * 128);
0835     offset += chan->gm_rpn_fine_tuning / 24;
0836 
0837 #ifdef SNDRV_EMUX_USE_RAW_EFFECT
0838     /* add initial pitch correction */
0839     if (chan->private) {
0840         struct snd_emux_effect_table *fx = chan->private;
0841         if (fx->flag[EMUX_FX_INIT_PITCH])
0842             offset += fx->val[EMUX_FX_INIT_PITCH];
0843     }
0844 #endif
0845 
0846     /* 0xe000: root pitch */
0847     offset += 0xe000 + vp->reg.rate_offset;
0848     offset += vp->emu->pitch_shift;
0849     LIMITVALUE(offset, 0, 0xffff);
0850     if (offset == vp->apitch)
0851         return 0; /* unchanged */
0852     vp->apitch = offset;
0853     return 1; /* value changed */
0854 }
0855 
0856 /*
0857  * Get the bank number assigned to the channel
0858  */
0859 static int
0860 get_bank(struct snd_emux_port *port, struct snd_midi_channel *chan)
0861 {
0862     int val;
0863 
0864     switch (port->chset.midi_mode) {
0865     case SNDRV_MIDI_MODE_XG:
0866         val = chan->control[MIDI_CTL_MSB_BANK];
0867         if (val == 127)
0868             return 128; /* return drum bank */
0869         return chan->control[MIDI_CTL_LSB_BANK];
0870 
0871     case SNDRV_MIDI_MODE_GS:
0872         if (chan->drum_channel)
0873             return 128;
0874         /* ignore LSB (bank map) */
0875         return chan->control[MIDI_CTL_MSB_BANK];
0876         
0877     default:
0878         if (chan->drum_channel)
0879             return 128;
0880         return chan->control[MIDI_CTL_MSB_BANK];
0881     }
0882 }
0883 
0884 
0885 /* Look for the zones matching with the given note and velocity.
0886  * The resultant zones are stored on table.
0887  */
0888 static int
0889 get_zone(struct snd_emux *emu, struct snd_emux_port *port,
0890      int *notep, int vel, struct snd_midi_channel *chan,
0891      struct snd_sf_zone **table)
0892 {
0893     int preset, bank, def_preset, def_bank;
0894 
0895     bank = get_bank(port, chan);
0896     preset = chan->midi_program;
0897 
0898     if (SF_IS_DRUM_BANK(bank)) {
0899         def_preset = port->ctrls[EMUX_MD_DEF_DRUM];
0900         def_bank = bank;
0901     } else {
0902         def_preset = preset;
0903         def_bank = port->ctrls[EMUX_MD_DEF_BANK];
0904     }
0905 
0906     return snd_soundfont_search_zone(emu->sflist, notep, vel, preset, bank,
0907                      def_preset, def_bank,
0908                      table, SNDRV_EMUX_MAX_MULTI_VOICES);
0909 }
0910 
0911 /*
0912  */
0913 void
0914 snd_emux_init_voices(struct snd_emux *emu)
0915 {
0916     struct snd_emux_voice *vp;
0917     int i;
0918     unsigned long flags;
0919 
0920     spin_lock_irqsave(&emu->voice_lock, flags);
0921     for (i = 0; i < emu->max_voices; i++) {
0922         vp = &emu->voices[i];
0923         vp->ch = -1; /* not used */
0924         vp->state = SNDRV_EMUX_ST_OFF;
0925         vp->chan = NULL;
0926         vp->port = NULL;
0927         vp->time = 0;
0928         vp->emu = emu;
0929         vp->hw = emu->hw;
0930     }
0931     spin_unlock_irqrestore(&emu->voice_lock, flags);
0932 }
0933 
0934 /*
0935  */
0936 void snd_emux_lock_voice(struct snd_emux *emu, int voice)
0937 {
0938     unsigned long flags;
0939 
0940     spin_lock_irqsave(&emu->voice_lock, flags);
0941     if (emu->voices[voice].state == SNDRV_EMUX_ST_OFF)
0942         emu->voices[voice].state = SNDRV_EMUX_ST_LOCKED;
0943     else
0944         snd_printk(KERN_WARNING
0945                "invalid voice for lock %d (state = %x)\n",
0946                voice, emu->voices[voice].state);
0947     spin_unlock_irqrestore(&emu->voice_lock, flags);
0948 }
0949 
0950 EXPORT_SYMBOL(snd_emux_lock_voice);
0951 
0952 /*
0953  */
0954 void snd_emux_unlock_voice(struct snd_emux *emu, int voice)
0955 {
0956     unsigned long flags;
0957 
0958     spin_lock_irqsave(&emu->voice_lock, flags);
0959     if (emu->voices[voice].state == SNDRV_EMUX_ST_LOCKED)
0960         emu->voices[voice].state = SNDRV_EMUX_ST_OFF;
0961     else
0962         snd_printk(KERN_WARNING
0963                "invalid voice for unlock %d (state = %x)\n",
0964                voice, emu->voices[voice].state);
0965     spin_unlock_irqrestore(&emu->voice_lock, flags);
0966 }
0967 
0968 EXPORT_SYMBOL(snd_emux_unlock_voice);