0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <linux/export.h>
0012 #include "emux_voice.h"
0013 #include <sound/asoundef.h>
0014
0015
0016
0017
0018
0019
0020
0021
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
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;
0064 nvoices = get_zone(emu, port, ¬e, vel, chan, table);
0065 if (! nvoices)
0066 return;
0067
0068
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
0076
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
0084
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
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;
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
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
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
0169
0170
0171
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
0180 emu->ops.release(vp);
0181 }
0182 }
0183 spin_unlock_irqrestore(&emu->voice_lock, flags);
0184 }
0185
0186
0187
0188
0189
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++;
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
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
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
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
0308
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
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
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
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
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
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
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
0468
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
0490
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
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
0531
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
0543
0544
0545 static void
0546 setup_voice(struct snd_emux_voice *vp)
0547 {
0548 struct soundfont_voice_parm *parm;
0549 int pitch;
0550
0551
0552 vp->reg = vp->zone->v;
0553
0554 #ifdef SNDRV_EMUX_USE_RAW_EFFECT
0555 snd_emux_setup_effect(vp);
0556 #endif
0557
0558
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
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
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
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
0602 vp->vtarget = 0;
0603 #if 0
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
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
0645 if (vp->reg.fixpan > 0)
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)
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
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
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
0680
0681
0682
0683
0684
0685
0686
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
0737
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
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
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;
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;
0801 }
0802
0803
0804
0805
0806
0807
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
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
0826 offset += chan->midi_pitchbend * chan->gm_rpn_pitch_bend_range / 3072;
0827 }
0828
0829
0830
0831
0832
0833
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
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
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;
0852 vp->apitch = offset;
0853 return 1;
0854 }
0855
0856
0857
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;
0869 return chan->control[MIDI_CTL_LSB_BANK];
0870
0871 case SNDRV_MIDI_MODE_GS:
0872 if (chan->drum_channel)
0873 return 128;
0874
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
0886
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;
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);