2 * Midi synth routines for the Emu8k/Emu10k1
4 * Copyright (C) 1999 Steve Ratcliffe
5 * Copyright (c) 1999-2000 Takashi Iwai <tiwai@suse.de>
7 * Contains code based on awe_wave.c by Takashi Iwai
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 #include "emux_voice.h"
26 #include <sound/asoundef.h>
33 * Ensure a value is between two points
34 * macro evaluates its args more than once, so changed to upper-case.
36 #define LIMITVALUE(x, a, b) do { if ((x) < (a)) (x) = (a); else if ((x) > (b)) (x) = (b); } while (0)
37 #define LIMITMAX(x, a) do {if ((x) > (a)) (x) = (a); } while (0)
39 static int get_zone(snd_emux_t *emu, snd_emux_port_t *port, int *notep, int vel, snd_midi_channel_t *chan, snd_sf_zone_t **table);
40 static int get_bank(snd_emux_port_t *port, snd_midi_channel_t *chan);
41 static void terminate_note1(snd_emux_t *emu, int note, snd_midi_channel_t *chan, int free);
42 static void exclusive_note_off(snd_emux_t *emu, snd_emux_port_t *port, int exclass);
43 static void terminate_voice(snd_emux_t *emu, snd_emux_voice_t *vp, int free);
44 static void update_voice(snd_emux_t *emu, snd_emux_voice_t *vp, int update);
45 static void setup_voice(snd_emux_voice_t *vp);
46 static int calc_pan(snd_emux_voice_t *vp);
47 static int calc_volume(snd_emux_voice_t *vp);
48 static int calc_pitch(snd_emux_voice_t *vp);
55 snd_emux_note_on(void *p, int note, int vel, snd_midi_channel_t *chan)
60 snd_sf_zone_t *table[SNDRV_EMUX_MAX_MULTI_VOICES];
62 snd_emux_port_t *port;
65 snd_assert(port != NULL && chan != NULL, return);
68 snd_assert(emu != NULL, return);
69 snd_assert(emu->ops.get_voice != NULL, return);
70 snd_assert(emu->ops.trigger != NULL, return);
72 key = note; /* remember the original note */
73 nvoices = get_zone(emu, port, ¬e, vel, chan, table);
77 /* exclusive note off */
78 for (i = 0; i < nvoices; i++) {
79 snd_sf_zone_t *zp = table[i];
80 if (zp && zp->v.exclusiveClass)
81 exclusive_note_off(emu, port, zp->v.exclusiveClass);
84 #if 0 // seems not necessary
85 /* Turn off the same note on the same channel. */
86 terminate_note1(emu, key, chan, 0);
89 spin_lock_irqsave(&emu->voice_lock, flags);
90 for (i = 0; i < nvoices; i++) {
92 /* set up each voice parameter */
93 /* at this stage, we don't trigger the voice yet. */
98 vp = emu->ops.get_voice(emu, port);
99 if (vp == NULL || vp->ch < 0)
101 snd_assert(vp->emu != NULL && vp->hw != NULL, return);
102 if (STATE_IS_PLAYING(vp->state))
103 emu->ops.terminate(vp);
105 vp->time = emu->use_time++;
112 if (vp->zone->sample)
113 vp->block = vp->zone->sample->block;
119 vp->state = SNDRV_EMUX_ST_STANDBY;
120 if (emu->ops.prepare) {
121 vp->state = SNDRV_EMUX_ST_OFF;
122 if (emu->ops.prepare(vp) >= 0)
123 vp->state = SNDRV_EMUX_ST_STANDBY;
127 /* start envelope now */
128 for (i = 0; i < emu->max_voices; i++) {
129 vp = &emu->voices[i];
130 if (vp->state == SNDRV_EMUX_ST_STANDBY &&
132 emu->ops.trigger(vp);
133 vp->state = SNDRV_EMUX_ST_ON;
134 vp->ontime = jiffies; /* remember the trigger timing */
137 spin_unlock_irqrestore(&emu->voice_lock, flags);
139 #ifdef SNDRV_EMUX_USE_RAW_EFFECT
140 if (port->port_mode == SNDRV_EMUX_PORT_MODE_OSS_SYNTH) {
141 /* clear voice position for the next note on this channel */
142 snd_emux_effect_table_t *fx = chan->private;
144 fx->flag[EMUX_FX_SAMPLE_START] = 0;
145 fx->flag[EMUX_FX_COARSE_SAMPLE_START] = 0;
152 * Release a note in response to a midi note off.
155 snd_emux_note_off(void *p, int note, int vel, snd_midi_channel_t *chan)
159 snd_emux_voice_t *vp;
161 snd_emux_port_t *port;
164 snd_assert(port != NULL && chan != NULL, return);
167 snd_assert(emu != NULL, return);
168 snd_assert(emu->ops.release != NULL, return);
170 spin_lock_irqsave(&emu->voice_lock, flags);
171 for (ch = 0; ch < emu->max_voices; ch++) {
172 vp = &emu->voices[ch];
173 if (STATE_IS_PLAYING(vp->state) &&
174 vp->chan == chan && vp->key == note) {
175 vp->time = emu->use_time++;
176 vp->state = SNDRV_EMUX_ST_RELEASED;
177 if (vp->ontime == jiffies) {
178 /* if note-off is sent too shortly after
179 * note-on, emuX engine cannot produce the sound
180 * correctly. so we'll release this note
181 * a bit later via timer callback.
183 vp->state = SNDRV_EMUX_ST_PENDING;
184 if (! emu->timer_active) {
185 emu->tlist.expires = jiffies + 1;
186 add_timer(&emu->tlist);
187 emu->timer_active = 1;
190 /* ok now release the note */
191 emu->ops.release(vp);
194 spin_unlock_irqrestore(&emu->voice_lock, flags);
200 * release the pending note-offs
202 void snd_emux_timer_callback(unsigned long data)
204 snd_emux_t *emu = (snd_emux_t*) data;
205 snd_emux_voice_t *vp;
206 int ch, do_again = 0;
208 spin_lock(&emu->voice_lock);
209 for (ch = 0; ch < emu->max_voices; ch++) {
210 vp = &emu->voices[ch];
211 if (vp->state == SNDRV_EMUX_ST_PENDING) {
212 if (vp->ontime == jiffies)
213 do_again++; /* release this at the next interrupt */
215 emu->ops.release(vp);
216 vp->state = SNDRV_EMUX_ST_RELEASED;
221 emu->tlist.expires = jiffies + 1;
222 add_timer(&emu->tlist);
223 emu->timer_active = 1;
225 emu->timer_active = 0;
226 spin_unlock(&emu->voice_lock);
230 * key pressure change
233 snd_emux_key_press(void *p, int note, int vel, snd_midi_channel_t *chan)
237 snd_emux_voice_t *vp;
239 snd_emux_port_t *port;
242 snd_assert(port != NULL && chan != NULL, return);
245 snd_assert(emu != NULL, return);
246 snd_assert(emu->ops.update != NULL, return);
248 spin_lock_irqsave(&emu->voice_lock, flags);
249 for (ch = 0; ch < emu->max_voices; ch++) {
250 vp = &emu->voices[ch];
251 if (vp->state == SNDRV_EMUX_ST_ON &&
252 vp->chan == chan && vp->key == note) {
254 update_voice(emu, vp, SNDRV_EMUX_UPDATE_VOLUME);
257 spin_unlock_irqrestore(&emu->voice_lock, flags);
262 * Modulate the voices which belong to the channel
265 snd_emux_update_channel(snd_emux_port_t *port, snd_midi_channel_t *chan, int update)
268 snd_emux_voice_t *vp;
276 snd_assert(emu != NULL, return);
277 snd_assert(emu->ops.update != NULL, return);
279 spin_lock_irqsave(&emu->voice_lock, flags);
280 for (i = 0; i < emu->max_voices; i++) {
281 vp = &emu->voices[i];
282 if (vp->chan == chan)
283 update_voice(emu, vp, update);
285 spin_unlock_irqrestore(&emu->voice_lock, flags);
289 * Modulate all the voices which belong to the port.
292 snd_emux_update_port(snd_emux_port_t *port, int update)
295 snd_emux_voice_t *vp;
303 snd_assert(emu != NULL, return);
304 snd_assert(emu->ops.update != NULL, return);
306 spin_lock_irqsave(&emu->voice_lock, flags);
307 for (i = 0; i < emu->max_voices; i++) {
308 vp = &emu->voices[i];
309 if (vp->port == port)
310 update_voice(emu, vp, update);
312 spin_unlock_irqrestore(&emu->voice_lock, flags);
317 * Deal with a controler type event. This includes all types of
318 * control events, not just the midi controllers
321 snd_emux_control(void *p, int type, snd_midi_channel_t *chan)
323 snd_emux_port_t *port;
326 snd_assert(port != NULL && chan != NULL, return);
329 case MIDI_CTL_MSB_MAIN_VOLUME:
330 case MIDI_CTL_MSB_EXPRESSION:
331 snd_emux_update_channel(port, chan, SNDRV_EMUX_UPDATE_VOLUME);
334 case MIDI_CTL_MSB_PAN:
335 snd_emux_update_channel(port, chan, SNDRV_EMUX_UPDATE_PAN);
338 case MIDI_CTL_SOFT_PEDAL:
339 #ifdef SNDRV_EMUX_USE_RAW_EFFECT
340 /* FIXME: this is an emulation */
341 snd_emux_send_effect(port, chan, EMUX_FX_CUTOFF, -160,
346 case MIDI_CTL_PITCHBEND:
347 snd_emux_update_channel(port, chan, SNDRV_EMUX_UPDATE_PITCH);
350 case MIDI_CTL_MSB_MODWHEEL:
351 case MIDI_CTL_CHAN_PRESSURE:
352 snd_emux_update_channel(port, chan,
353 SNDRV_EMUX_UPDATE_FMMOD |
354 SNDRV_EMUX_UPDATE_FM2FRQ2);
359 if (port->chset.midi_mode == SNDRV_MIDI_MODE_XG) {
360 snd_emux_xg_control(port, chan, type);
366 * for Emu10k1 - release at least 1 voice currently using
369 snd_emux_release_voice(snd_emux_t *emu)
376 * terminate note - if free flag is true, free the terminated voice
379 terminate_note1(snd_emux_t *emu, int note, snd_midi_channel_t *chan, int free)
382 snd_emux_voice_t *vp;
385 spin_lock_irqsave(&emu->voice_lock, flags);
386 for (i = 0; i < emu->max_voices; i++) {
387 vp = &emu->voices[i];
388 if (STATE_IS_PLAYING(vp->state) && vp->chan == chan &&
390 terminate_voice(emu, vp, free);
392 spin_unlock_irqrestore(&emu->voice_lock, flags);
397 * terminate note - exported for midi emulation
400 snd_emux_terminate_note(void *p, int note, snd_midi_channel_t *chan)
403 snd_emux_port_t *port;
406 snd_assert(port != NULL && chan != NULL, return);
409 snd_assert(emu != NULL, return);
410 snd_assert(emu->ops.terminate != NULL, return);
412 terminate_note1(emu, note, chan, 1);
417 * Terminate all the notes
420 snd_emux_terminate_all(snd_emux_t *emu)
423 snd_emux_voice_t *vp;
426 spin_lock_irqsave(&emu->voice_lock, flags);
427 for (i = 0; i < emu->max_voices; i++) {
428 vp = &emu->voices[i];
429 if (STATE_IS_PLAYING(vp->state))
430 terminate_voice(emu, vp, 0);
431 if (vp->state == SNDRV_EMUX_ST_OFF) {
432 if (emu->ops.free_voice)
433 emu->ops.free_voice(vp);
435 emu->ops.reset(emu, i);
439 /* initialize allocation time */
441 spin_unlock_irqrestore(&emu->voice_lock, flags);
446 * Terminate all voices associated with the given port
449 snd_emux_sounds_off_all(snd_emux_port_t *port)
453 snd_emux_voice_t *vp;
456 snd_assert(port != NULL, return);
458 snd_assert(emu != NULL, return);
459 snd_assert(emu->ops.terminate != NULL, return);
461 spin_lock_irqsave(&emu->voice_lock, flags);
462 for (i = 0; i < emu->max_voices; i++) {
463 vp = &emu->voices[i];
464 if (STATE_IS_PLAYING(vp->state) &&
466 terminate_voice(emu, vp, 0);
467 if (vp->state == SNDRV_EMUX_ST_OFF) {
468 if (emu->ops.free_voice)
469 emu->ops.free_voice(vp);
471 emu->ops.reset(emu, i);
474 spin_unlock_irqrestore(&emu->voice_lock, flags);
479 * Terminate all voices that have the same exclusive class. This
480 * is mainly for drums.
483 exclusive_note_off(snd_emux_t *emu, snd_emux_port_t *port, int exclass)
485 snd_emux_voice_t *vp;
489 spin_lock_irqsave(&emu->voice_lock, flags);
490 for (i = 0; i < emu->max_voices; i++) {
491 vp = &emu->voices[i];
492 if (STATE_IS_PLAYING(vp->state) && vp->port == port &&
493 vp->reg.exclusiveClass == exclass) {
494 terminate_voice(emu, vp, 0);
497 spin_unlock_irqrestore(&emu->voice_lock, flags);
502 * if free flag is true, call free_voice after termination
505 terminate_voice(snd_emux_t *emu, snd_emux_voice_t *vp, int free)
507 emu->ops.terminate(vp);
508 vp->time = emu->use_time++;
513 vp->state = SNDRV_EMUX_ST_OFF;
514 if (free && emu->ops.free_voice)
515 emu->ops.free_voice(vp);
523 update_voice(snd_emux_t *emu, snd_emux_voice_t *vp, int update)
525 if (!STATE_IS_PLAYING(vp->state))
528 if (vp->chan == NULL || vp->port == NULL)
530 if (update & SNDRV_EMUX_UPDATE_VOLUME)
532 if (update & SNDRV_EMUX_UPDATE_PITCH)
534 if (update & SNDRV_EMUX_UPDATE_PAN) {
535 if (! calc_pan(vp) && (update == SNDRV_EMUX_UPDATE_PAN))
538 emu->ops.update(vp, update);
543 /* table for volume target calculation */
544 static unsigned short voltarget[16] = {
545 0xEAC0, 0xE0C8, 0xD740, 0xCE20, 0xC560, 0xBD08, 0xB500, 0xAD58,
546 0xA5F8, 0x9EF0, 0x9830, 0x91C0, 0x8B90, 0x85A8, 0x8000, 0x7A90
550 #define LO_BYTE(v) ((v) & 0xff)
551 #define HI_BYTE(v) (((v) >> 8) & 0xff)
554 * Sets up the voice structure by calculating some values that
555 * will be needed later.
558 setup_voice(snd_emux_voice_t *vp)
560 soundfont_voice_parm_t *parm;
563 /* copy the original register values */
564 vp->reg = vp->zone->v;
566 #ifdef SNDRV_EMUX_USE_RAW_EFFECT
567 snd_emux_setup_effect(vp);
579 parm = &vp->reg.parm;
581 /* compute filter target and correct modulation parameters */
582 if (LO_BYTE(parm->modatkhld) >= 0x80 && parm->moddelay >= 0x8000) {
583 parm->moddelay = 0xbfff;
584 pitch = (HI_BYTE(parm->pefe) << 4) + vp->apitch;
587 /* calculate filter target */
588 vp->ftarget = parm->cutoff + LO_BYTE(parm->pefe);
589 LIMITVALUE(vp->ftarget, 0, 255);
592 vp->ftarget = parm->cutoff;
597 /* compute pitch target */
598 if (pitch != 0xffff) {
599 vp->ptarget = 1 << (pitch >> 12);
600 if (pitch & 0x800) vp->ptarget += (vp->ptarget*0x102e)/0x2710;
601 if (pitch & 0x400) vp->ptarget += (vp->ptarget*0x764)/0x2710;
602 if (pitch & 0x200) vp->ptarget += (vp->ptarget*0x389)/0x2710;
603 vp->ptarget += (vp->ptarget >> 1);
604 if (vp->ptarget > 0xffff) vp->ptarget = 0xffff;
606 vp->ptarget = 0xffff;
608 if (LO_BYTE(parm->modatkhld) >= 0x80) {
609 parm->modatkhld &= ~0xff;
610 parm->modatkhld |= 0x7f;
613 /* compute volume target and correct volume parameters */
615 #if 0 /* FIXME: this leads to some clicks.. */
616 if (LO_BYTE(parm->volatkhld) >= 0x80 && parm->voldelay >= 0x8000) {
617 parm->voldelay = 0xbfff;
618 vp->vtarget = voltarget[vp->avol % 0x10] >> (vp->avol >> 4);
622 if (LO_BYTE(parm->volatkhld) >= 0x80) {
623 parm->volatkhld &= ~0xff;
624 parm->volatkhld |= 0x7f;
629 * calculate pitch parameter
631 static unsigned char pan_volumes[256] = {
632 0x00,0x03,0x06,0x09,0x0c,0x0f,0x12,0x14,0x17,0x1a,0x1d,0x20,0x22,0x25,0x28,0x2a,
633 0x2d,0x30,0x32,0x35,0x37,0x3a,0x3c,0x3f,0x41,0x44,0x46,0x49,0x4b,0x4d,0x50,0x52,
634 0x54,0x57,0x59,0x5b,0x5d,0x60,0x62,0x64,0x66,0x68,0x6a,0x6c,0x6f,0x71,0x73,0x75,
635 0x77,0x79,0x7b,0x7c,0x7e,0x80,0x82,0x84,0x86,0x88,0x89,0x8b,0x8d,0x8f,0x90,0x92,
636 0x94,0x96,0x97,0x99,0x9a,0x9c,0x9e,0x9f,0xa1,0xa2,0xa4,0xa5,0xa7,0xa8,0xaa,0xab,
637 0xad,0xae,0xaf,0xb1,0xb2,0xb3,0xb5,0xb6,0xb7,0xb9,0xba,0xbb,0xbc,0xbe,0xbf,0xc0,
638 0xc1,0xc2,0xc3,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xcb,0xcc,0xcd,0xce,0xcf,0xd0,0xd1,
639 0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd7,0xd8,0xd9,0xda,0xdb,0xdc,0xdc,0xdd,0xde,0xdf,
640 0xdf,0xe0,0xe1,0xe2,0xe2,0xe3,0xe4,0xe4,0xe5,0xe6,0xe6,0xe7,0xe8,0xe8,0xe9,0xe9,
641 0xea,0xeb,0xeb,0xec,0xec,0xed,0xed,0xee,0xee,0xef,0xef,0xf0,0xf0,0xf1,0xf1,0xf1,
642 0xf2,0xf2,0xf3,0xf3,0xf3,0xf4,0xf4,0xf5,0xf5,0xf5,0xf6,0xf6,0xf6,0xf7,0xf7,0xf7,
643 0xf7,0xf8,0xf8,0xf8,0xf9,0xf9,0xf9,0xf9,0xf9,0xfa,0xfa,0xfa,0xfa,0xfb,0xfb,0xfb,
644 0xfb,0xfb,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,
645 0xfd,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,
646 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
647 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
651 calc_pan(snd_emux_voice_t *vp)
653 snd_midi_channel_t *chan = vp->chan;
656 /* pan & loop start (pan 8bit, MSB, 0:right, 0xff:left) */
657 if (vp->reg.fixpan > 0) /* 0-127 */
658 pan = 255 - (int)vp->reg.fixpan * 2;
660 pan = chan->control[MIDI_CTL_MSB_PAN] - 64;
661 if (vp->reg.pan >= 0) /* 0-127 */
662 pan += vp->reg.pan - 64;
663 pan = 127 - (int)pan * 2;
665 LIMITVALUE(pan, 0, 255);
667 if (vp->emu->linear_panning) {
668 /* assuming linear volume */
669 if (pan != vp->apan) {
674 vp->aaux = (-pan) & 0xff;
679 /* using volume table */
680 if (vp->apan != (int)pan_volumes[pan]) {
681 vp->apan = pan_volumes[pan];
682 vp->aaux = pan_volumes[255 - pan];
691 * calculate volume attenuation
693 * Voice volume is controlled by volume attenuation parameter.
694 * So volume becomes maximum when avol is 0 (no attenuation), and
695 * minimum when 255 (-96dB or silence).
698 /* tables for volume->attenuation calculation */
699 static unsigned char voltab1[128] = {
700 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
701 0x63, 0x2b, 0x29, 0x28, 0x27, 0x26, 0x25, 0x24, 0x23, 0x22,
702 0x21, 0x20, 0x1f, 0x1e, 0x1e, 0x1d, 0x1c, 0x1b, 0x1b, 0x1a,
703 0x19, 0x19, 0x18, 0x17, 0x17, 0x16, 0x16, 0x15, 0x15, 0x14,
704 0x14, 0x13, 0x13, 0x13, 0x12, 0x12, 0x11, 0x11, 0x11, 0x10,
705 0x10, 0x10, 0x0f, 0x0f, 0x0f, 0x0e, 0x0e, 0x0e, 0x0e, 0x0d,
706 0x0d, 0x0d, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0b, 0x0b, 0x0b,
707 0x0b, 0x0a, 0x0a, 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09,
708 0x08, 0x08, 0x08, 0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x06,
709 0x06, 0x06, 0x06, 0x06, 0x05, 0x05, 0x05, 0x05, 0x05, 0x04,
710 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02,
711 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01,
712 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
715 static unsigned char voltab2[128] = {
716 0x32, 0x31, 0x30, 0x2f, 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x2a,
717 0x29, 0x28, 0x27, 0x26, 0x25, 0x24, 0x24, 0x23, 0x22, 0x21,
718 0x21, 0x20, 0x1f, 0x1e, 0x1e, 0x1d, 0x1c, 0x1c, 0x1b, 0x1a,
719 0x1a, 0x19, 0x19, 0x18, 0x18, 0x17, 0x16, 0x16, 0x15, 0x15,
720 0x14, 0x14, 0x13, 0x13, 0x13, 0x12, 0x12, 0x11, 0x11, 0x10,
721 0x10, 0x10, 0x0f, 0x0f, 0x0f, 0x0e, 0x0e, 0x0e, 0x0d, 0x0d,
722 0x0d, 0x0c, 0x0c, 0x0c, 0x0b, 0x0b, 0x0b, 0x0b, 0x0a, 0x0a,
723 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x08, 0x08, 0x08,
724 0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x07, 0x06, 0x06, 0x06,
725 0x06, 0x06, 0x06, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
726 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03,
727 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01,
728 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00
731 static unsigned char expressiontab[128] = {
732 0x7f, 0x6c, 0x62, 0x5a, 0x54, 0x50, 0x4b, 0x48, 0x45, 0x42,
733 0x40, 0x3d, 0x3b, 0x39, 0x38, 0x36, 0x34, 0x33, 0x31, 0x30,
734 0x2f, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, 0x27, 0x26, 0x25,
735 0x24, 0x24, 0x23, 0x22, 0x21, 0x21, 0x20, 0x1f, 0x1e, 0x1e,
736 0x1d, 0x1d, 0x1c, 0x1b, 0x1b, 0x1a, 0x1a, 0x19, 0x18, 0x18,
737 0x17, 0x17, 0x16, 0x16, 0x15, 0x15, 0x15, 0x14, 0x14, 0x13,
738 0x13, 0x12, 0x12, 0x11, 0x11, 0x11, 0x10, 0x10, 0x0f, 0x0f,
739 0x0f, 0x0e, 0x0e, 0x0e, 0x0d, 0x0d, 0x0d, 0x0c, 0x0c, 0x0c,
740 0x0b, 0x0b, 0x0b, 0x0a, 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09,
741 0x08, 0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x06, 0x06, 0x06,
742 0x06, 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03,
743 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01,
744 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
748 * Magic to calculate the volume (actually attenuation) from all the
749 * voice and channels parameters.
752 calc_volume(snd_emux_voice_t *vp)
755 int main_vol, expression_vol, master_vol;
756 snd_midi_channel_t *chan = vp->chan;
757 snd_emux_port_t *port = vp->port;
759 expression_vol = chan->control[MIDI_CTL_MSB_EXPRESSION];
760 LIMITMAX(vp->velocity, 127);
761 LIMITVALUE(expression_vol, 0, 127);
762 if (port->port_mode == SNDRV_EMUX_PORT_MODE_OSS_SYNTH) {
764 main_vol = chan->control[MIDI_CTL_MSB_MAIN_VOLUME];
765 vol = (vp->velocity * main_vol * expression_vol) / (127*127);
766 vol = vol * vp->reg.amplitude / 127;
768 LIMITVALUE(vol, 0, 127);
770 /* calc to attenuation */
771 vol = snd_sf_vol_table[vol];
774 main_vol = chan->control[MIDI_CTL_MSB_MAIN_VOLUME] * vp->reg.amplitude / 127;
775 LIMITVALUE(main_vol, 0, 127);
777 vol = voltab1[main_vol] + voltab2[vp->velocity];
779 vol += vp->reg.attenuation;
780 vol += ((0x100 - vol) * expressiontab[expression_vol])/128;
783 master_vol = port->chset.gs_master_volume;
784 LIMITVALUE(master_vol, 0, 127);
785 vol += snd_sf_vol_table[master_vol];
786 vol += port->volume_atten;
788 #ifdef SNDRV_EMUX_USE_RAW_EFFECT
790 snd_emux_effect_table_t *fx = chan->private;
791 vol += fx->val[EMUX_FX_ATTEN];
795 LIMITVALUE(vol, 0, 255);
797 return 0; /* value unchanged */
800 if (!SF_IS_DRUM_BANK(get_bank(port, chan))
801 && LO_BYTE(vp->reg.parm.volatkhld) < 0x7d) {
803 if (vp->velocity < 70)
806 atten = vp->velocity;
807 vp->acutoff = (atten * vp->reg.parm.cutoff + 0xa0) >> 7;
809 vp->acutoff = vp->reg.parm.cutoff;
812 return 1; /* value changed */
816 * calculate pitch offset
818 * 0xE000 is no pitch offset at 44100Hz sample.
819 * Every 4096 is one octave.
823 calc_pitch(snd_emux_voice_t *vp)
825 snd_midi_channel_t *chan = vp->chan;
828 /* calculate offset */
829 if (vp->reg.fixkey >= 0) {
830 offset = (vp->reg.fixkey - vp->reg.root) * 4096 / 12;
832 offset = (vp->note - vp->reg.root) * 4096 / 12;
834 offset = (offset * vp->reg.scaleTuning) / 100;
835 offset += vp->reg.tune * 4096 / 1200;
836 if (chan->midi_pitchbend != 0) {
837 /* (128 * 8192: 1 semitone) ==> (4096: 12 semitones) */
838 offset += chan->midi_pitchbend * chan->gm_rpn_pitch_bend_range / 3072;
842 * coarse = -8192 to 8192 (100 cent per 128)
843 * fine = -8192 to 8192 (max=100cent)
845 /* 4096 = 1200 cents in emu8000 parameter */
846 offset += chan->gm_rpn_coarse_tuning * 4096 / (12 * 128);
847 offset += chan->gm_rpn_fine_tuning / 24;
849 #ifdef SNDRV_EMUX_USE_RAW_EFFECT
850 /* add initial pitch correction */
852 snd_emux_effect_table_t *fx = chan->private;
853 if (fx->flag[EMUX_FX_INIT_PITCH])
854 offset += fx->val[EMUX_FX_INIT_PITCH];
858 /* 0xe000: root pitch */
859 offset += 0xe000 + vp->reg.rate_offset;
860 offset += vp->emu->pitch_shift;
861 LIMITVALUE(offset, 0, 0xffff);
862 if (offset == vp->apitch)
863 return 0; /* unchanged */
865 return 1; /* value changed */
869 * Get the bank number assigned to the channel
872 get_bank(snd_emux_port_t *port, snd_midi_channel_t *chan)
876 switch (port->chset.midi_mode) {
877 case SNDRV_MIDI_MODE_XG:
878 val = chan->control[MIDI_CTL_MSB_BANK];
880 return 128; /* return drum bank */
881 return chan->control[MIDI_CTL_LSB_BANK];
883 case SNDRV_MIDI_MODE_GS:
884 if (chan->drum_channel)
886 /* ignore LSB (bank map) */
887 return chan->control[MIDI_CTL_MSB_BANK];
890 if (chan->drum_channel)
892 return chan->control[MIDI_CTL_MSB_BANK];
897 /* Look for the zones matching with the given note and velocity.
898 * The resultant zones are stored on table.
901 get_zone(snd_emux_t *emu, snd_emux_port_t *port,
902 int *notep, int vel, snd_midi_channel_t *chan, snd_sf_zone_t **table)
904 int preset, bank, def_preset, def_bank;
906 bank = get_bank(port, chan);
907 preset = chan->midi_program;
909 if (SF_IS_DRUM_BANK(bank)) {
910 def_preset = port->ctrls[EMUX_MD_DEF_DRUM];
914 def_bank = port->ctrls[EMUX_MD_DEF_BANK];
917 return snd_soundfont_search_zone(emu->sflist, notep, vel, preset, bank,
918 def_preset, def_bank,
919 table, SNDRV_EMUX_MAX_MULTI_VOICES);
925 snd_emux_init_voices(snd_emux_t *emu)
927 snd_emux_voice_t *vp;
931 spin_lock_irqsave(&emu->voice_lock, flags);
932 for (i = 0; i < emu->max_voices; i++) {
933 vp = &emu->voices[i];
934 vp->ch = -1; /* not used */
935 vp->state = SNDRV_EMUX_ST_OFF;
942 spin_unlock_irqrestore(&emu->voice_lock, flags);
947 void snd_emux_lock_voice(snd_emux_t *emu, int voice)
951 spin_lock_irqsave(&emu->voice_lock, flags);
952 if (emu->voices[voice].state == SNDRV_EMUX_ST_OFF)
953 emu->voices[voice].state = SNDRV_EMUX_ST_LOCKED;
955 snd_printk("invalid voice for lock %d (state = %x)\n",
956 voice, emu->voices[voice].state);
957 spin_unlock_irqrestore(&emu->voice_lock, flags);
962 void snd_emux_unlock_voice(snd_emux_t *emu, int voice)
966 spin_lock_irqsave(&emu->voice_lock, flags);
967 if (emu->voices[voice].state == SNDRV_EMUX_ST_LOCKED)
968 emu->voices[voice].state = SNDRV_EMUX_ST_OFF;
970 snd_printk("invalid voice for unlock %d (state = %x)\n",
971 voice, emu->voices[voice].state);
972 spin_unlock_irqrestore(&emu->voice_lock, flags);