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(struct snd_emux
*emu
, struct snd_emux_port
*port
,
40 int *notep
, int vel
, struct snd_midi_channel
*chan
,
41 struct snd_sf_zone
**table
);
42 static int get_bank(struct snd_emux_port
*port
, struct snd_midi_channel
*chan
);
43 static void terminate_note1(struct snd_emux
*emu
, int note
,
44 struct snd_midi_channel
*chan
, int free
);
45 static void exclusive_note_off(struct snd_emux
*emu
, struct snd_emux_port
*port
,
47 static void terminate_voice(struct snd_emux
*emu
, struct snd_emux_voice
*vp
, int free
);
48 static void update_voice(struct snd_emux
*emu
, struct snd_emux_voice
*vp
, int update
);
49 static void setup_voice(struct snd_emux_voice
*vp
);
50 static int calc_pan(struct snd_emux_voice
*vp
);
51 static int calc_volume(struct snd_emux_voice
*vp
);
52 static int calc_pitch(struct snd_emux_voice
*vp
);
59 snd_emux_note_on(void *p
, int note
, int vel
, struct snd_midi_channel
*chan
)
63 struct snd_emux_voice
*vp
;
64 struct snd_sf_zone
*table
[SNDRV_EMUX_MAX_MULTI_VOICES
];
66 struct snd_emux_port
*port
;
69 snd_assert(port
!= NULL
&& chan
!= NULL
, return);
72 snd_assert(emu
!= NULL
, return);
73 snd_assert(emu
->ops
.get_voice
!= NULL
, return);
74 snd_assert(emu
->ops
.trigger
!= NULL
, return);
76 key
= note
; /* remember the original note */
77 nvoices
= get_zone(emu
, port
, ¬e
, vel
, chan
, table
);
81 /* exclusive note off */
82 for (i
= 0; i
< nvoices
; i
++) {
83 struct snd_sf_zone
*zp
= table
[i
];
84 if (zp
&& zp
->v
.exclusiveClass
)
85 exclusive_note_off(emu
, port
, zp
->v
.exclusiveClass
);
88 #if 0 // seems not necessary
89 /* Turn off the same note on the same channel. */
90 terminate_note1(emu
, key
, chan
, 0);
93 spin_lock_irqsave(&emu
->voice_lock
, flags
);
94 for (i
= 0; i
< nvoices
; i
++) {
96 /* set up each voice parameter */
97 /* at this stage, we don't trigger the voice yet. */
102 vp
= emu
->ops
.get_voice(emu
, port
);
103 if (vp
== NULL
|| vp
->ch
< 0)
105 if (STATE_IS_PLAYING(vp
->state
))
106 emu
->ops
.terminate(vp
);
108 vp
->time
= emu
->use_time
++;
115 if (vp
->zone
->sample
)
116 vp
->block
= vp
->zone
->sample
->block
;
122 vp
->state
= SNDRV_EMUX_ST_STANDBY
;
123 if (emu
->ops
.prepare
) {
124 vp
->state
= SNDRV_EMUX_ST_OFF
;
125 if (emu
->ops
.prepare(vp
) >= 0)
126 vp
->state
= SNDRV_EMUX_ST_STANDBY
;
130 /* start envelope now */
131 for (i
= 0; i
< emu
->max_voices
; i
++) {
132 vp
= &emu
->voices
[i
];
133 if (vp
->state
== SNDRV_EMUX_ST_STANDBY
&&
135 emu
->ops
.trigger(vp
);
136 vp
->state
= SNDRV_EMUX_ST_ON
;
137 vp
->ontime
= jiffies
; /* remember the trigger timing */
140 spin_unlock_irqrestore(&emu
->voice_lock
, flags
);
142 #ifdef SNDRV_EMUX_USE_RAW_EFFECT
143 if (port
->port_mode
== SNDRV_EMUX_PORT_MODE_OSS_SYNTH
) {
144 /* clear voice position for the next note on this channel */
145 struct snd_emux_effect_table
*fx
= chan
->private;
147 fx
->flag
[EMUX_FX_SAMPLE_START
] = 0;
148 fx
->flag
[EMUX_FX_COARSE_SAMPLE_START
] = 0;
155 * Release a note in response to a midi note off.
158 snd_emux_note_off(void *p
, int note
, int vel
, struct snd_midi_channel
*chan
)
161 struct snd_emux
*emu
;
162 struct snd_emux_voice
*vp
;
164 struct snd_emux_port
*port
;
167 snd_assert(port
!= NULL
&& chan
!= NULL
, return);
170 snd_assert(emu
!= NULL
, return);
171 snd_assert(emu
->ops
.release
!= NULL
, return);
173 spin_lock_irqsave(&emu
->voice_lock
, flags
);
174 for (ch
= 0; ch
< emu
->max_voices
; ch
++) {
175 vp
= &emu
->voices
[ch
];
176 if (STATE_IS_PLAYING(vp
->state
) &&
177 vp
->chan
== chan
&& vp
->key
== note
) {
178 vp
->state
= SNDRV_EMUX_ST_RELEASED
;
179 if (vp
->ontime
== jiffies
) {
180 /* if note-off is sent too shortly after
181 * note-on, emuX engine cannot produce the sound
182 * correctly. so we'll release this note
183 * a bit later via timer callback.
185 vp
->state
= SNDRV_EMUX_ST_PENDING
;
186 if (! emu
->timer_active
) {
187 emu
->tlist
.expires
= jiffies
+ 1;
188 add_timer(&emu
->tlist
);
189 emu
->timer_active
= 1;
192 /* ok now release the note */
193 emu
->ops
.release(vp
);
196 spin_unlock_irqrestore(&emu
->voice_lock
, flags
);
202 * release the pending note-offs
204 void snd_emux_timer_callback(unsigned long data
)
206 struct snd_emux
*emu
= (struct snd_emux
*) data
;
207 struct snd_emux_voice
*vp
;
209 int ch
, do_again
= 0;
211 spin_lock_irqsave(&emu
->voice_lock
, flags
);
212 for (ch
= 0; ch
< emu
->max_voices
; ch
++) {
213 vp
= &emu
->voices
[ch
];
214 if (vp
->state
== SNDRV_EMUX_ST_PENDING
) {
215 if (vp
->ontime
== jiffies
)
216 do_again
++; /* release this at the next interrupt */
218 emu
->ops
.release(vp
);
219 vp
->state
= SNDRV_EMUX_ST_RELEASED
;
224 emu
->tlist
.expires
= jiffies
+ 1;
225 add_timer(&emu
->tlist
);
226 emu
->timer_active
= 1;
228 emu
->timer_active
= 0;
229 spin_unlock_irqrestore(&emu
->voice_lock
, flags
);
233 * key pressure change
236 snd_emux_key_press(void *p
, int note
, int vel
, struct snd_midi_channel
*chan
)
239 struct snd_emux
*emu
;
240 struct snd_emux_voice
*vp
;
242 struct snd_emux_port
*port
;
245 snd_assert(port
!= NULL
&& chan
!= NULL
, return);
248 snd_assert(emu
!= NULL
, return);
249 snd_assert(emu
->ops
.update
!= NULL
, return);
251 spin_lock_irqsave(&emu
->voice_lock
, flags
);
252 for (ch
= 0; ch
< emu
->max_voices
; ch
++) {
253 vp
= &emu
->voices
[ch
];
254 if (vp
->state
== SNDRV_EMUX_ST_ON
&&
255 vp
->chan
== chan
&& vp
->key
== note
) {
257 update_voice(emu
, vp
, SNDRV_EMUX_UPDATE_VOLUME
);
260 spin_unlock_irqrestore(&emu
->voice_lock
, flags
);
265 * Modulate the voices which belong to the channel
268 snd_emux_update_channel(struct snd_emux_port
*port
, struct snd_midi_channel
*chan
, int update
)
270 struct snd_emux
*emu
;
271 struct snd_emux_voice
*vp
;
279 snd_assert(emu
!= NULL
, return);
280 snd_assert(emu
->ops
.update
!= NULL
, return);
282 spin_lock_irqsave(&emu
->voice_lock
, flags
);
283 for (i
= 0; i
< emu
->max_voices
; i
++) {
284 vp
= &emu
->voices
[i
];
285 if (vp
->chan
== chan
)
286 update_voice(emu
, vp
, update
);
288 spin_unlock_irqrestore(&emu
->voice_lock
, flags
);
292 * Modulate all the voices which belong to the port.
295 snd_emux_update_port(struct snd_emux_port
*port
, int update
)
297 struct snd_emux
*emu
;
298 struct snd_emux_voice
*vp
;
306 snd_assert(emu
!= NULL
, return);
307 snd_assert(emu
->ops
.update
!= NULL
, return);
309 spin_lock_irqsave(&emu
->voice_lock
, flags
);
310 for (i
= 0; i
< emu
->max_voices
; i
++) {
311 vp
= &emu
->voices
[i
];
312 if (vp
->port
== port
)
313 update_voice(emu
, vp
, update
);
315 spin_unlock_irqrestore(&emu
->voice_lock
, flags
);
320 * Deal with a controler type event. This includes all types of
321 * control events, not just the midi controllers
324 snd_emux_control(void *p
, int type
, struct snd_midi_channel
*chan
)
326 struct snd_emux_port
*port
;
329 snd_assert(port
!= NULL
&& chan
!= NULL
, return);
332 case MIDI_CTL_MSB_MAIN_VOLUME
:
333 case MIDI_CTL_MSB_EXPRESSION
:
334 snd_emux_update_channel(port
, chan
, SNDRV_EMUX_UPDATE_VOLUME
);
337 case MIDI_CTL_MSB_PAN
:
338 snd_emux_update_channel(port
, chan
, SNDRV_EMUX_UPDATE_PAN
);
341 case MIDI_CTL_SOFT_PEDAL
:
342 #ifdef SNDRV_EMUX_USE_RAW_EFFECT
343 /* FIXME: this is an emulation */
344 snd_emux_send_effect(port
, chan
, EMUX_FX_CUTOFF
, -160,
349 case MIDI_CTL_PITCHBEND
:
350 snd_emux_update_channel(port
, chan
, SNDRV_EMUX_UPDATE_PITCH
);
353 case MIDI_CTL_MSB_MODWHEEL
:
354 case MIDI_CTL_CHAN_PRESSURE
:
355 snd_emux_update_channel(port
, chan
,
356 SNDRV_EMUX_UPDATE_FMMOD
|
357 SNDRV_EMUX_UPDATE_FM2FRQ2
);
362 if (port
->chset
.midi_mode
== SNDRV_MIDI_MODE_XG
) {
363 snd_emux_xg_control(port
, chan
, type
);
369 * terminate note - if free flag is true, free the terminated voice
372 terminate_note1(struct snd_emux
*emu
, int note
, struct snd_midi_channel
*chan
, int free
)
375 struct snd_emux_voice
*vp
;
378 spin_lock_irqsave(&emu
->voice_lock
, flags
);
379 for (i
= 0; i
< emu
->max_voices
; i
++) {
380 vp
= &emu
->voices
[i
];
381 if (STATE_IS_PLAYING(vp
->state
) && vp
->chan
== chan
&&
383 terminate_voice(emu
, vp
, free
);
385 spin_unlock_irqrestore(&emu
->voice_lock
, flags
);
390 * terminate note - exported for midi emulation
393 snd_emux_terminate_note(void *p
, int note
, struct snd_midi_channel
*chan
)
395 struct snd_emux
*emu
;
396 struct snd_emux_port
*port
;
399 snd_assert(port
!= NULL
&& chan
!= NULL
, return);
402 snd_assert(emu
!= NULL
, return);
403 snd_assert(emu
->ops
.terminate
!= NULL
, return);
405 terminate_note1(emu
, note
, chan
, 1);
410 * Terminate all the notes
413 snd_emux_terminate_all(struct snd_emux
*emu
)
416 struct snd_emux_voice
*vp
;
419 spin_lock_irqsave(&emu
->voice_lock
, flags
);
420 for (i
= 0; i
< emu
->max_voices
; i
++) {
421 vp
= &emu
->voices
[i
];
422 if (STATE_IS_PLAYING(vp
->state
))
423 terminate_voice(emu
, vp
, 0);
424 if (vp
->state
== SNDRV_EMUX_ST_OFF
) {
425 if (emu
->ops
.free_voice
)
426 emu
->ops
.free_voice(vp
);
428 emu
->ops
.reset(emu
, i
);
432 /* initialize allocation time */
434 spin_unlock_irqrestore(&emu
->voice_lock
, flags
);
439 * Terminate all voices associated with the given port
442 snd_emux_sounds_off_all(struct snd_emux_port
*port
)
445 struct snd_emux
*emu
;
446 struct snd_emux_voice
*vp
;
449 snd_assert(port
!= NULL
, return);
451 snd_assert(emu
!= NULL
, return);
452 snd_assert(emu
->ops
.terminate
!= NULL
, return);
454 spin_lock_irqsave(&emu
->voice_lock
, flags
);
455 for (i
= 0; i
< emu
->max_voices
; i
++) {
456 vp
= &emu
->voices
[i
];
457 if (STATE_IS_PLAYING(vp
->state
) &&
459 terminate_voice(emu
, vp
, 0);
460 if (vp
->state
== SNDRV_EMUX_ST_OFF
) {
461 if (emu
->ops
.free_voice
)
462 emu
->ops
.free_voice(vp
);
464 emu
->ops
.reset(emu
, i
);
467 spin_unlock_irqrestore(&emu
->voice_lock
, flags
);
472 * Terminate all voices that have the same exclusive class. This
473 * is mainly for drums.
476 exclusive_note_off(struct snd_emux
*emu
, struct snd_emux_port
*port
, int exclass
)
478 struct snd_emux_voice
*vp
;
482 spin_lock_irqsave(&emu
->voice_lock
, flags
);
483 for (i
= 0; i
< emu
->max_voices
; i
++) {
484 vp
= &emu
->voices
[i
];
485 if (STATE_IS_PLAYING(vp
->state
) && vp
->port
== port
&&
486 vp
->reg
.exclusiveClass
== exclass
) {
487 terminate_voice(emu
, vp
, 0);
490 spin_unlock_irqrestore(&emu
->voice_lock
, flags
);
495 * if free flag is true, call free_voice after termination
498 terminate_voice(struct snd_emux
*emu
, struct snd_emux_voice
*vp
, int free
)
500 emu
->ops
.terminate(vp
);
501 vp
->time
= emu
->use_time
++;
506 vp
->state
= SNDRV_EMUX_ST_OFF
;
507 if (free
&& emu
->ops
.free_voice
)
508 emu
->ops
.free_voice(vp
);
516 update_voice(struct snd_emux
*emu
, struct snd_emux_voice
*vp
, int update
)
518 if (!STATE_IS_PLAYING(vp
->state
))
521 if (vp
->chan
== NULL
|| vp
->port
== NULL
)
523 if (update
& SNDRV_EMUX_UPDATE_VOLUME
)
525 if (update
& SNDRV_EMUX_UPDATE_PITCH
)
527 if (update
& SNDRV_EMUX_UPDATE_PAN
) {
528 if (! calc_pan(vp
) && (update
== SNDRV_EMUX_UPDATE_PAN
))
531 emu
->ops
.update(vp
, update
);
536 /* table for volume target calculation */
537 static unsigned short voltarget
[16] = {
538 0xEAC0, 0xE0C8, 0xD740, 0xCE20, 0xC560, 0xBD08, 0xB500, 0xAD58,
539 0xA5F8, 0x9EF0, 0x9830, 0x91C0, 0x8B90, 0x85A8, 0x8000, 0x7A90
543 #define LO_BYTE(v) ((v) & 0xff)
544 #define HI_BYTE(v) (((v) >> 8) & 0xff)
547 * Sets up the voice structure by calculating some values that
548 * will be needed later.
551 setup_voice(struct snd_emux_voice
*vp
)
553 struct soundfont_voice_parm
*parm
;
556 /* copy the original register values */
557 vp
->reg
= vp
->zone
->v
;
559 #ifdef SNDRV_EMUX_USE_RAW_EFFECT
560 snd_emux_setup_effect(vp
);
572 parm
= &vp
->reg
.parm
;
574 /* compute filter target and correct modulation parameters */
575 if (LO_BYTE(parm
->modatkhld
) >= 0x80 && parm
->moddelay
>= 0x8000) {
576 parm
->moddelay
= 0xbfff;
577 pitch
= (HI_BYTE(parm
->pefe
) << 4) + vp
->apitch
;
580 /* calculate filter target */
581 vp
->ftarget
= parm
->cutoff
+ LO_BYTE(parm
->pefe
);
582 LIMITVALUE(vp
->ftarget
, 0, 255);
585 vp
->ftarget
= parm
->cutoff
;
590 /* compute pitch target */
591 if (pitch
!= 0xffff) {
592 vp
->ptarget
= 1 << (pitch
>> 12);
593 if (pitch
& 0x800) vp
->ptarget
+= (vp
->ptarget
*0x102e)/0x2710;
594 if (pitch
& 0x400) vp
->ptarget
+= (vp
->ptarget
*0x764)/0x2710;
595 if (pitch
& 0x200) vp
->ptarget
+= (vp
->ptarget
*0x389)/0x2710;
596 vp
->ptarget
+= (vp
->ptarget
>> 1);
597 if (vp
->ptarget
> 0xffff) vp
->ptarget
= 0xffff;
599 vp
->ptarget
= 0xffff;
601 if (LO_BYTE(parm
->modatkhld
) >= 0x80) {
602 parm
->modatkhld
&= ~0xff;
603 parm
->modatkhld
|= 0x7f;
606 /* compute volume target and correct volume parameters */
608 #if 0 /* FIXME: this leads to some clicks.. */
609 if (LO_BYTE(parm
->volatkhld
) >= 0x80 && parm
->voldelay
>= 0x8000) {
610 parm
->voldelay
= 0xbfff;
611 vp
->vtarget
= voltarget
[vp
->avol
% 0x10] >> (vp
->avol
>> 4);
615 if (LO_BYTE(parm
->volatkhld
) >= 0x80) {
616 parm
->volatkhld
&= ~0xff;
617 parm
->volatkhld
|= 0x7f;
622 * calculate pitch parameter
624 static unsigned char pan_volumes
[256] = {
625 0x00,0x03,0x06,0x09,0x0c,0x0f,0x12,0x14,0x17,0x1a,0x1d,0x20,0x22,0x25,0x28,0x2a,
626 0x2d,0x30,0x32,0x35,0x37,0x3a,0x3c,0x3f,0x41,0x44,0x46,0x49,0x4b,0x4d,0x50,0x52,
627 0x54,0x57,0x59,0x5b,0x5d,0x60,0x62,0x64,0x66,0x68,0x6a,0x6c,0x6f,0x71,0x73,0x75,
628 0x77,0x79,0x7b,0x7c,0x7e,0x80,0x82,0x84,0x86,0x88,0x89,0x8b,0x8d,0x8f,0x90,0x92,
629 0x94,0x96,0x97,0x99,0x9a,0x9c,0x9e,0x9f,0xa1,0xa2,0xa4,0xa5,0xa7,0xa8,0xaa,0xab,
630 0xad,0xae,0xaf,0xb1,0xb2,0xb3,0xb5,0xb6,0xb7,0xb9,0xba,0xbb,0xbc,0xbe,0xbf,0xc0,
631 0xc1,0xc2,0xc3,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xcb,0xcc,0xcd,0xce,0xcf,0xd0,0xd1,
632 0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd7,0xd8,0xd9,0xda,0xdb,0xdc,0xdc,0xdd,0xde,0xdf,
633 0xdf,0xe0,0xe1,0xe2,0xe2,0xe3,0xe4,0xe4,0xe5,0xe6,0xe6,0xe7,0xe8,0xe8,0xe9,0xe9,
634 0xea,0xeb,0xeb,0xec,0xec,0xed,0xed,0xee,0xee,0xef,0xef,0xf0,0xf0,0xf1,0xf1,0xf1,
635 0xf2,0xf2,0xf3,0xf3,0xf3,0xf4,0xf4,0xf5,0xf5,0xf5,0xf6,0xf6,0xf6,0xf7,0xf7,0xf7,
636 0xf7,0xf8,0xf8,0xf8,0xf9,0xf9,0xf9,0xf9,0xf9,0xfa,0xfa,0xfa,0xfa,0xfb,0xfb,0xfb,
637 0xfb,0xfb,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,
638 0xfd,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,
639 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
640 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
644 calc_pan(struct snd_emux_voice
*vp
)
646 struct snd_midi_channel
*chan
= vp
->chan
;
649 /* pan & loop start (pan 8bit, MSB, 0:right, 0xff:left) */
650 if (vp
->reg
.fixpan
> 0) /* 0-127 */
651 pan
= 255 - (int)vp
->reg
.fixpan
* 2;
653 pan
= chan
->control
[MIDI_CTL_MSB_PAN
] - 64;
654 if (vp
->reg
.pan
>= 0) /* 0-127 */
655 pan
+= vp
->reg
.pan
- 64;
656 pan
= 127 - (int)pan
* 2;
658 LIMITVALUE(pan
, 0, 255);
660 if (vp
->emu
->linear_panning
) {
661 /* assuming linear volume */
662 if (pan
!= vp
->apan
) {
667 vp
->aaux
= (-pan
) & 0xff;
672 /* using volume table */
673 if (vp
->apan
!= (int)pan_volumes
[pan
]) {
674 vp
->apan
= pan_volumes
[pan
];
675 vp
->aaux
= pan_volumes
[255 - pan
];
684 * calculate volume attenuation
686 * Voice volume is controlled by volume attenuation parameter.
687 * So volume becomes maximum when avol is 0 (no attenuation), and
688 * minimum when 255 (-96dB or silence).
691 /* tables for volume->attenuation calculation */
692 static unsigned char voltab1
[128] = {
693 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
694 0x63, 0x2b, 0x29, 0x28, 0x27, 0x26, 0x25, 0x24, 0x23, 0x22,
695 0x21, 0x20, 0x1f, 0x1e, 0x1e, 0x1d, 0x1c, 0x1b, 0x1b, 0x1a,
696 0x19, 0x19, 0x18, 0x17, 0x17, 0x16, 0x16, 0x15, 0x15, 0x14,
697 0x14, 0x13, 0x13, 0x13, 0x12, 0x12, 0x11, 0x11, 0x11, 0x10,
698 0x10, 0x10, 0x0f, 0x0f, 0x0f, 0x0e, 0x0e, 0x0e, 0x0e, 0x0d,
699 0x0d, 0x0d, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0b, 0x0b, 0x0b,
700 0x0b, 0x0a, 0x0a, 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09,
701 0x08, 0x08, 0x08, 0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x06,
702 0x06, 0x06, 0x06, 0x06, 0x05, 0x05, 0x05, 0x05, 0x05, 0x04,
703 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02,
704 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01,
705 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
708 static unsigned char voltab2
[128] = {
709 0x32, 0x31, 0x30, 0x2f, 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x2a,
710 0x29, 0x28, 0x27, 0x26, 0x25, 0x24, 0x24, 0x23, 0x22, 0x21,
711 0x21, 0x20, 0x1f, 0x1e, 0x1e, 0x1d, 0x1c, 0x1c, 0x1b, 0x1a,
712 0x1a, 0x19, 0x19, 0x18, 0x18, 0x17, 0x16, 0x16, 0x15, 0x15,
713 0x14, 0x14, 0x13, 0x13, 0x13, 0x12, 0x12, 0x11, 0x11, 0x10,
714 0x10, 0x10, 0x0f, 0x0f, 0x0f, 0x0e, 0x0e, 0x0e, 0x0d, 0x0d,
715 0x0d, 0x0c, 0x0c, 0x0c, 0x0b, 0x0b, 0x0b, 0x0b, 0x0a, 0x0a,
716 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x08, 0x08, 0x08,
717 0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x07, 0x06, 0x06, 0x06,
718 0x06, 0x06, 0x06, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
719 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03,
720 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01,
721 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00
724 static unsigned char expressiontab
[128] = {
725 0x7f, 0x6c, 0x62, 0x5a, 0x54, 0x50, 0x4b, 0x48, 0x45, 0x42,
726 0x40, 0x3d, 0x3b, 0x39, 0x38, 0x36, 0x34, 0x33, 0x31, 0x30,
727 0x2f, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, 0x27, 0x26, 0x25,
728 0x24, 0x24, 0x23, 0x22, 0x21, 0x21, 0x20, 0x1f, 0x1e, 0x1e,
729 0x1d, 0x1d, 0x1c, 0x1b, 0x1b, 0x1a, 0x1a, 0x19, 0x18, 0x18,
730 0x17, 0x17, 0x16, 0x16, 0x15, 0x15, 0x15, 0x14, 0x14, 0x13,
731 0x13, 0x12, 0x12, 0x11, 0x11, 0x11, 0x10, 0x10, 0x0f, 0x0f,
732 0x0f, 0x0e, 0x0e, 0x0e, 0x0d, 0x0d, 0x0d, 0x0c, 0x0c, 0x0c,
733 0x0b, 0x0b, 0x0b, 0x0a, 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09,
734 0x08, 0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x06, 0x06, 0x06,
735 0x06, 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03,
736 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01,
737 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
741 * Magic to calculate the volume (actually attenuation) from all the
742 * voice and channels parameters.
745 calc_volume(struct snd_emux_voice
*vp
)
748 int main_vol
, expression_vol
, master_vol
;
749 struct snd_midi_channel
*chan
= vp
->chan
;
750 struct snd_emux_port
*port
= vp
->port
;
752 expression_vol
= chan
->control
[MIDI_CTL_MSB_EXPRESSION
];
753 LIMITMAX(vp
->velocity
, 127);
754 LIMITVALUE(expression_vol
, 0, 127);
755 if (port
->port_mode
== SNDRV_EMUX_PORT_MODE_OSS_SYNTH
) {
757 main_vol
= chan
->control
[MIDI_CTL_MSB_MAIN_VOLUME
];
758 vol
= (vp
->velocity
* main_vol
* expression_vol
) / (127*127);
759 vol
= vol
* vp
->reg
.amplitude
/ 127;
761 LIMITVALUE(vol
, 0, 127);
763 /* calc to attenuation */
764 vol
= snd_sf_vol_table
[vol
];
767 main_vol
= chan
->control
[MIDI_CTL_MSB_MAIN_VOLUME
] * vp
->reg
.amplitude
/ 127;
768 LIMITVALUE(main_vol
, 0, 127);
770 vol
= voltab1
[main_vol
] + voltab2
[vp
->velocity
];
772 vol
+= vp
->reg
.attenuation
;
773 vol
+= ((0x100 - vol
) * expressiontab
[expression_vol
])/128;
776 master_vol
= port
->chset
.gs_master_volume
;
777 LIMITVALUE(master_vol
, 0, 127);
778 vol
+= snd_sf_vol_table
[master_vol
];
779 vol
+= port
->volume_atten
;
781 #ifdef SNDRV_EMUX_USE_RAW_EFFECT
783 struct snd_emux_effect_table
*fx
= chan
->private;
784 vol
+= fx
->val
[EMUX_FX_ATTEN
];
788 LIMITVALUE(vol
, 0, 255);
790 return 0; /* value unchanged */
793 if (!SF_IS_DRUM_BANK(get_bank(port
, chan
))
794 && LO_BYTE(vp
->reg
.parm
.volatkhld
) < 0x7d) {
796 if (vp
->velocity
< 70)
799 atten
= vp
->velocity
;
800 vp
->acutoff
= (atten
* vp
->reg
.parm
.cutoff
+ 0xa0) >> 7;
802 vp
->acutoff
= vp
->reg
.parm
.cutoff
;
805 return 1; /* value changed */
809 * calculate pitch offset
811 * 0xE000 is no pitch offset at 44100Hz sample.
812 * Every 4096 is one octave.
816 calc_pitch(struct snd_emux_voice
*vp
)
818 struct snd_midi_channel
*chan
= vp
->chan
;
821 /* calculate offset */
822 if (vp
->reg
.fixkey
>= 0) {
823 offset
= (vp
->reg
.fixkey
- vp
->reg
.root
) * 4096 / 12;
825 offset
= (vp
->note
- vp
->reg
.root
) * 4096 / 12;
827 offset
= (offset
* vp
->reg
.scaleTuning
) / 100;
828 offset
+= vp
->reg
.tune
* 4096 / 1200;
829 if (chan
->midi_pitchbend
!= 0) {
830 /* (128 * 8192: 1 semitone) ==> (4096: 12 semitones) */
831 offset
+= chan
->midi_pitchbend
* chan
->gm_rpn_pitch_bend_range
/ 3072;
835 * coarse = -8192 to 8192 (100 cent per 128)
836 * fine = -8192 to 8192 (max=100cent)
838 /* 4096 = 1200 cents in emu8000 parameter */
839 offset
+= chan
->gm_rpn_coarse_tuning
* 4096 / (12 * 128);
840 offset
+= chan
->gm_rpn_fine_tuning
/ 24;
842 #ifdef SNDRV_EMUX_USE_RAW_EFFECT
843 /* add initial pitch correction */
845 struct snd_emux_effect_table
*fx
= chan
->private;
846 if (fx
->flag
[EMUX_FX_INIT_PITCH
])
847 offset
+= fx
->val
[EMUX_FX_INIT_PITCH
];
851 /* 0xe000: root pitch */
852 offset
+= 0xe000 + vp
->reg
.rate_offset
;
853 offset
+= vp
->emu
->pitch_shift
;
854 LIMITVALUE(offset
, 0, 0xffff);
855 if (offset
== vp
->apitch
)
856 return 0; /* unchanged */
858 return 1; /* value changed */
862 * Get the bank number assigned to the channel
865 get_bank(struct snd_emux_port
*port
, struct snd_midi_channel
*chan
)
869 switch (port
->chset
.midi_mode
) {
870 case SNDRV_MIDI_MODE_XG
:
871 val
= chan
->control
[MIDI_CTL_MSB_BANK
];
873 return 128; /* return drum bank */
874 return chan
->control
[MIDI_CTL_LSB_BANK
];
876 case SNDRV_MIDI_MODE_GS
:
877 if (chan
->drum_channel
)
879 /* ignore LSB (bank map) */
880 return chan
->control
[MIDI_CTL_MSB_BANK
];
883 if (chan
->drum_channel
)
885 return chan
->control
[MIDI_CTL_MSB_BANK
];
890 /* Look for the zones matching with the given note and velocity.
891 * The resultant zones are stored on table.
894 get_zone(struct snd_emux
*emu
, struct snd_emux_port
*port
,
895 int *notep
, int vel
, struct snd_midi_channel
*chan
,
896 struct snd_sf_zone
**table
)
898 int preset
, bank
, def_preset
, def_bank
;
900 bank
= get_bank(port
, chan
);
901 preset
= chan
->midi_program
;
903 if (SF_IS_DRUM_BANK(bank
)) {
904 def_preset
= port
->ctrls
[EMUX_MD_DEF_DRUM
];
908 def_bank
= port
->ctrls
[EMUX_MD_DEF_BANK
];
911 return snd_soundfont_search_zone(emu
->sflist
, notep
, vel
, preset
, bank
,
912 def_preset
, def_bank
,
913 table
, SNDRV_EMUX_MAX_MULTI_VOICES
);
919 snd_emux_init_voices(struct snd_emux
*emu
)
921 struct snd_emux_voice
*vp
;
925 spin_lock_irqsave(&emu
->voice_lock
, flags
);
926 for (i
= 0; i
< emu
->max_voices
; i
++) {
927 vp
= &emu
->voices
[i
];
928 vp
->ch
= -1; /* not used */
929 vp
->state
= SNDRV_EMUX_ST_OFF
;
936 spin_unlock_irqrestore(&emu
->voice_lock
, flags
);
941 void snd_emux_lock_voice(struct snd_emux
*emu
, int voice
)
945 spin_lock_irqsave(&emu
->voice_lock
, flags
);
946 if (emu
->voices
[voice
].state
== SNDRV_EMUX_ST_OFF
)
947 emu
->voices
[voice
].state
= SNDRV_EMUX_ST_LOCKED
;
949 snd_printk("invalid voice for lock %d (state = %x)\n",
950 voice
, emu
->voices
[voice
].state
);
951 spin_unlock_irqrestore(&emu
->voice_lock
, flags
);
956 void snd_emux_unlock_voice(struct snd_emux
*emu
, int voice
)
960 spin_lock_irqsave(&emu
->voice_lock
, flags
);
961 if (emu
->voices
[voice
].state
== SNDRV_EMUX_ST_LOCKED
)
962 emu
->voices
[voice
].state
= SNDRV_EMUX_ST_OFF
;
964 snd_printk("invalid voice for unlock %d (state = %x)\n",
965 voice
, emu
->voices
[voice
].state
);
966 spin_unlock_irqrestore(&emu
->voice_lock
, flags
);