25 #include <linux/export.h>
37 #define LIMITVALUE(x, a, b) do { if ((x) < (a)) (x) = (a); else if ((x) > (b)) (x) = (b); } while (0)
38 #define LIMITMAX(x, a) do {if ((x) > (a)) (x) = (a); } while (0)
44 static void terminate_note1(
struct snd_emux *
emu,
int note,
78 nvoices = get_zone(emu, port, ¬e, vel, chan, table);
83 for (i = 0; i < nvoices; i++) {
85 if (zp && zp->
v.exclusiveClass)
86 exclusive_note_off(emu, port, zp->
v.exclusiveClass);
89 #if 0 // seems not necessary
91 terminate_note1(emu, key, chan, 0);
95 for (i = 0; i < nvoices; i++) {
100 if (table[i] ==
NULL)
103 vp = emu->
ops.get_voice(emu, port);
104 if (vp ==
NULL || vp->
ch < 0)
107 emu->
ops.terminate(vp);
116 if (vp->
zone->sample)
124 if (emu->
ops.prepare) {
126 if (emu->
ops.prepare(vp) >= 0)
136 emu->
ops.trigger(vp);
141 spin_unlock_irqrestore(&emu->
voice_lock, flags);
143 #ifdef SNDRV_EMUX_USE_RAW_EFFECT
179 vp->
chan == chan && vp->
key == note) {
195 emu->
ops.release(vp);
198 spin_unlock_irqrestore(&emu->
voice_lock, flags);
211 int ch, do_again = 0;
220 emu->
ops.release(vp);
231 spin_unlock_irqrestore(&emu->
voice_lock, flags);
258 vp->
chan == chan && vp->
key == note) {
263 spin_unlock_irqrestore(&emu->
voice_lock, flags);
288 if (vp->
chan == chan)
289 update_voice(emu, vp, update);
291 spin_unlock_irqrestore(&emu->
voice_lock, flags);
315 if (vp->
port == port)
316 update_voice(emu, vp, update);
318 spin_unlock_irqrestore(&emu->
voice_lock, flags);
346 #ifdef SNDRV_EMUX_USE_RAW_EFFECT
391 terminate_voice(emu, vp, free);
393 spin_unlock_irqrestore(&emu->
voice_lock, flags);
414 terminate_note1(emu, note, chan, 1);
432 terminate_voice(emu, vp, 0);
434 if (emu->
ops.free_voice)
435 emu->
ops.free_voice(vp);
437 emu->
ops.reset(emu, i);
443 spin_unlock_irqrestore(&emu->
voice_lock, flags);
470 terminate_voice(emu, vp, 0);
472 if (emu->
ops.free_voice)
473 emu->
ops.free_voice(vp);
475 emu->
ops.reset(emu, i);
478 spin_unlock_irqrestore(&emu->
voice_lock, flags);
497 vp->
reg.exclusiveClass == exclass) {
498 terminate_voice(emu, vp, 0);
501 spin_unlock_irqrestore(&emu->
voice_lock, flags);
511 emu->
ops.terminate(vp);
518 if (free && emu->
ops.free_voice)
519 emu->
ops.free_voice(vp);
539 if (! calc_pan(vp) && (update == SNDRV_EMUX_UPDATE_PAN))
542 emu->
ops.update(vp, update);
548 static unsigned short voltarget[16] = {
549 0xEAC0, 0xE0C8, 0xD740, 0xCE20, 0xC560, 0xBD08, 0xB500, 0xAD58,
550 0xA5F8, 0x9EF0, 0x9830, 0x91C0, 0x8B90, 0x85A8, 0x8000, 0x7A90
554 #define LO_BYTE(v) ((v) & 0xff)
555 #define HI_BYTE(v) (((v) >> 8) & 0xff)
570 #ifdef SNDRV_EMUX_USE_RAW_EFFECT
571 snd_emux_setup_effect(vp);
583 parm = &vp->
reg.parm;
602 if (pitch != 0xffff) {
603 vp->
ptarget = 1 << (pitch >> 12);
635 static unsigned char pan_volumes[256] = {
636 0x00,0x03,0x06,0x09,0x0c,0x0f,0x12,0x14,0x17,0x1a,0x1d,0x20,0x22,0x25,0x28,0x2a,
637 0x2d,0x30,0x32,0x35,0x37,0x3a,0x3c,0x3f,0x41,0x44,0x46,0x49,0x4b,0x4d,0x50,0x52,
638 0x54,0x57,0x59,0x5b,0x5d,0x60,0x62,0x64,0x66,0x68,0x6a,0x6c,0x6f,0x71,0x73,0x75,
639 0x77,0x79,0x7b,0x7c,0x7e,0x80,0x82,0x84,0x86,0x88,0x89,0x8b,0x8d,0x8f,0x90,0x92,
640 0x94,0x96,0x97,0x99,0x9a,0x9c,0x9e,0x9f,0xa1,0xa2,0xa4,0xa5,0xa7,0xa8,0xaa,0xab,
641 0xad,0xae,0xaf,0xb1,0xb2,0xb3,0xb5,0xb6,0xb7,0xb9,0xba,0xbb,0xbc,0xbe,0xbf,0xc0,
642 0xc1,0xc2,0xc3,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xcb,0xcc,0xcd,0xce,0xcf,0xd0,0xd1,
643 0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd7,0xd8,0xd9,0xda,0xdb,0xdc,0xdc,0xdd,0xde,0xdf,
644 0xdf,0xe0,0xe1,0xe2,0xe2,0xe3,0xe4,0xe4,0xe5,0xe6,0xe6,0xe7,0xe8,0xe8,0xe9,0xe9,
645 0xea,0xeb,0xeb,0xec,0xec,0xed,0xed,0xee,0xee,0xef,0xef,0xf0,0xf0,0xf1,0xf1,0xf1,
646 0xf2,0xf2,0xf3,0xf3,0xf3,0xf4,0xf4,0xf5,0xf5,0xf5,0xf6,0xf6,0xf6,0xf7,0xf7,0xf7,
647 0xf7,0xf8,0xf8,0xf8,0xf9,0xf9,0xf9,0xf9,0xf9,0xfa,0xfa,0xfa,0xfa,0xfb,0xfb,0xfb,
648 0xfb,0xfb,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,
649 0xfd,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,
650 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
651 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
661 if (vp->
reg.fixpan > 0)
662 pan = 255 - (
int)vp->
reg.fixpan * 2;
665 if (vp->
reg.pan >= 0)
666 pan += vp->
reg.pan - 64;
667 pan = 127 - (
int)pan * 2;
671 if (vp->
emu->linear_panning) {
673 if (pan != vp->
apan) {
678 vp->
aaux = (-pan) & 0xff;
684 if (vp->
apan != (
int)pan_volumes[pan]) {
685 vp->
apan = pan_volumes[pan];
686 vp->
aaux = pan_volumes[255 - pan];
703 static unsigned char voltab1[128] = {
704 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
705 0x63, 0x2b, 0x29, 0x28, 0x27, 0x26, 0x25, 0x24, 0x23, 0x22,
706 0x21, 0x20, 0x1f, 0x1e, 0x1e, 0x1d, 0x1c, 0x1b, 0x1b, 0x1a,
707 0x19, 0x19, 0x18, 0x17, 0x17, 0x16, 0x16, 0x15, 0x15, 0x14,
708 0x14, 0x13, 0x13, 0x13, 0x12, 0x12, 0x11, 0x11, 0x11, 0x10,
709 0x10, 0x10, 0x0f, 0x0f, 0x0f, 0x0e, 0x0e, 0x0e, 0x0e, 0x0d,
710 0x0d, 0x0d, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0b, 0x0b, 0x0b,
711 0x0b, 0x0a, 0x0a, 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09,
712 0x08, 0x08, 0x08, 0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x06,
713 0x06, 0x06, 0x06, 0x06, 0x05, 0x05, 0x05, 0x05, 0x05, 0x04,
714 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02,
715 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01,
716 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
719 static unsigned char voltab2[128] = {
720 0x32, 0x31, 0x30, 0x2f, 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x2a,
721 0x29, 0x28, 0x27, 0x26, 0x25, 0x24, 0x24, 0x23, 0x22, 0x21,
722 0x21, 0x20, 0x1f, 0x1e, 0x1e, 0x1d, 0x1c, 0x1c, 0x1b, 0x1a,
723 0x1a, 0x19, 0x19, 0x18, 0x18, 0x17, 0x16, 0x16, 0x15, 0x15,
724 0x14, 0x14, 0x13, 0x13, 0x13, 0x12, 0x12, 0x11, 0x11, 0x10,
725 0x10, 0x10, 0x0f, 0x0f, 0x0f, 0x0e, 0x0e, 0x0e, 0x0d, 0x0d,
726 0x0d, 0x0c, 0x0c, 0x0c, 0x0b, 0x0b, 0x0b, 0x0b, 0x0a, 0x0a,
727 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x08, 0x08, 0x08,
728 0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x07, 0x06, 0x06, 0x06,
729 0x06, 0x06, 0x06, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
730 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03,
731 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01,
732 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00
735 static unsigned char expressiontab[128] = {
736 0x7f, 0x6c, 0x62, 0x5a, 0x54, 0x50, 0x4b, 0x48, 0x45, 0x42,
737 0x40, 0x3d, 0x3b, 0x39, 0x38, 0x36, 0x34, 0x33, 0x31, 0x30,
738 0x2f, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, 0x27, 0x26, 0x25,
739 0x24, 0x24, 0x23, 0x22, 0x21, 0x21, 0x20, 0x1f, 0x1e, 0x1e,
740 0x1d, 0x1d, 0x1c, 0x1b, 0x1b, 0x1a, 0x1a, 0x19, 0x18, 0x18,
741 0x17, 0x17, 0x16, 0x16, 0x15, 0x15, 0x15, 0x14, 0x14, 0x13,
742 0x13, 0x12, 0x12, 0x11, 0x11, 0x11, 0x10, 0x10, 0x0f, 0x0f,
743 0x0f, 0x0e, 0x0e, 0x0e, 0x0d, 0x0d, 0x0d, 0x0c, 0x0c, 0x0c,
744 0x0b, 0x0b, 0x0b, 0x0a, 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09,
745 0x08, 0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x06, 0x06, 0x06,
746 0x06, 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03,
747 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01,
748 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
759 int main_vol, expression_vol, master_vol;
769 vol = (vp->
velocity * main_vol * expression_vol) / (127*127);
770 vol = vol * vp->
reg.amplitude / 127;
781 vol = voltab1[main_vol] + voltab2[vp->
velocity];
783 vol += vp->
reg.attenuation;
784 vol += ((0x100 -
vol) * expressiontab[expression_vol])/128;
787 master_vol = port->
chset.gs_master_volume;
792 #ifdef SNDRV_EMUX_USE_RAW_EFFECT
811 vp->
acutoff = (atten * vp->
reg.parm.cutoff + 0xa0) >> 7;
833 if (vp->
reg.fixkey >= 0) {
834 offset = (vp->
reg.fixkey - vp->
reg.root) * 4096 / 12;
836 offset = (vp->
note - vp->
reg.root) * 4096 / 12;
838 offset = (offset * vp->
reg.scaleTuning) / 100;
839 offset += vp->
reg.tune * 4096 / 1200;
853 #ifdef SNDRV_EMUX_USE_RAW_EFFECT
863 offset += 0xe000 + vp->
reg.rate_offset;
864 offset += vp->
emu->pitch_shift;
880 switch (port->
chset.midi_mode) {
909 int preset, bank, def_preset, def_bank;
911 bank = get_bank(port, chan);
923 def_preset, def_bank,
947 spin_unlock_irqrestore(&emu->
voice_lock, flags);
961 "invalid voice for lock %d (state = %x)\n",
962 voice, emu->
voices[voice].state);
963 spin_unlock_irqrestore(&emu->
voice_lock, flags);
979 "invalid voice for unlock %d (state = %x)\n",
980 voice, emu->
voices[voice].state);
981 spin_unlock_irqrestore(&emu->
voice_lock, flags);