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 controller 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 if (chan
->control
[type
] >= 64)
345 snd_emux_send_effect(port
, chan
, EMUX_FX_CUTOFF
, -160,
348 snd_emux_send_effect(port
, chan
, EMUX_FX_CUTOFF
, 0,
353 case MIDI_CTL_PITCHBEND
:
354 snd_emux_update_channel(port
, chan
, SNDRV_EMUX_UPDATE_PITCH
);
357 case MIDI_CTL_MSB_MODWHEEL
:
358 case MIDI_CTL_CHAN_PRESSURE
:
359 snd_emux_update_channel(port
, chan
,
360 SNDRV_EMUX_UPDATE_FMMOD
|
361 SNDRV_EMUX_UPDATE_FM2FRQ2
);
366 if (port
->chset
.midi_mode
== SNDRV_MIDI_MODE_XG
) {
367 snd_emux_xg_control(port
, chan
, type
);
373 * terminate note - if free flag is true, free the terminated voice
376 terminate_note1(struct snd_emux
*emu
, int note
, struct snd_midi_channel
*chan
, int free
)
379 struct snd_emux_voice
*vp
;
382 spin_lock_irqsave(&emu
->voice_lock
, flags
);
383 for (i
= 0; i
< emu
->max_voices
; i
++) {
384 vp
= &emu
->voices
[i
];
385 if (STATE_IS_PLAYING(vp
->state
) && vp
->chan
== chan
&&
387 terminate_voice(emu
, vp
, free
);
389 spin_unlock_irqrestore(&emu
->voice_lock
, flags
);
394 * terminate note - exported for midi emulation
397 snd_emux_terminate_note(void *p
, int note
, struct snd_midi_channel
*chan
)
399 struct snd_emux
*emu
;
400 struct snd_emux_port
*port
;
403 snd_assert(port
!= NULL
&& chan
!= NULL
, return);
406 snd_assert(emu
!= NULL
, return);
407 snd_assert(emu
->ops
.terminate
!= NULL
, return);
409 terminate_note1(emu
, note
, chan
, 1);
414 * Terminate all the notes
417 snd_emux_terminate_all(struct snd_emux
*emu
)
420 struct snd_emux_voice
*vp
;
423 spin_lock_irqsave(&emu
->voice_lock
, flags
);
424 for (i
= 0; i
< emu
->max_voices
; i
++) {
425 vp
= &emu
->voices
[i
];
426 if (STATE_IS_PLAYING(vp
->state
))
427 terminate_voice(emu
, vp
, 0);
428 if (vp
->state
== SNDRV_EMUX_ST_OFF
) {
429 if (emu
->ops
.free_voice
)
430 emu
->ops
.free_voice(vp
);
432 emu
->ops
.reset(emu
, i
);
436 /* initialize allocation time */
438 spin_unlock_irqrestore(&emu
->voice_lock
, flags
);
441 EXPORT_SYMBOL(snd_emux_terminate_all
);
444 * Terminate all voices associated with the given port
447 snd_emux_sounds_off_all(struct snd_emux_port
*port
)
450 struct snd_emux
*emu
;
451 struct snd_emux_voice
*vp
;
454 snd_assert(port
!= NULL
, return);
456 snd_assert(emu
!= NULL
, return);
457 snd_assert(emu
->ops
.terminate
!= NULL
, return);
459 spin_lock_irqsave(&emu
->voice_lock
, flags
);
460 for (i
= 0; i
< emu
->max_voices
; i
++) {
461 vp
= &emu
->voices
[i
];
462 if (STATE_IS_PLAYING(vp
->state
) &&
464 terminate_voice(emu
, vp
, 0);
465 if (vp
->state
== SNDRV_EMUX_ST_OFF
) {
466 if (emu
->ops
.free_voice
)
467 emu
->ops
.free_voice(vp
);
469 emu
->ops
.reset(emu
, i
);
472 spin_unlock_irqrestore(&emu
->voice_lock
, flags
);
477 * Terminate all voices that have the same exclusive class. This
478 * is mainly for drums.
481 exclusive_note_off(struct snd_emux
*emu
, struct snd_emux_port
*port
, int exclass
)
483 struct snd_emux_voice
*vp
;
487 spin_lock_irqsave(&emu
->voice_lock
, flags
);
488 for (i
= 0; i
< emu
->max_voices
; i
++) {
489 vp
= &emu
->voices
[i
];
490 if (STATE_IS_PLAYING(vp
->state
) && vp
->port
== port
&&
491 vp
->reg
.exclusiveClass
== exclass
) {
492 terminate_voice(emu
, vp
, 0);
495 spin_unlock_irqrestore(&emu
->voice_lock
, flags
);
500 * if free flag is true, call free_voice after termination
503 terminate_voice(struct snd_emux
*emu
, struct snd_emux_voice
*vp
, int free
)
505 emu
->ops
.terminate(vp
);
506 vp
->time
= emu
->use_time
++;
511 vp
->state
= SNDRV_EMUX_ST_OFF
;
512 if (free
&& emu
->ops
.free_voice
)
513 emu
->ops
.free_voice(vp
);
521 update_voice(struct snd_emux
*emu
, struct snd_emux_voice
*vp
, int update
)
523 if (!STATE_IS_PLAYING(vp
->state
))
526 if (vp
->chan
== NULL
|| vp
->port
== NULL
)
528 if (update
& SNDRV_EMUX_UPDATE_VOLUME
)
530 if (update
& SNDRV_EMUX_UPDATE_PITCH
)
532 if (update
& SNDRV_EMUX_UPDATE_PAN
) {
533 if (! calc_pan(vp
) && (update
== SNDRV_EMUX_UPDATE_PAN
))
536 emu
->ops
.update(vp
, update
);
541 /* table for volume target calculation */
542 static unsigned short voltarget
[16] = {
543 0xEAC0, 0xE0C8, 0xD740, 0xCE20, 0xC560, 0xBD08, 0xB500, 0xAD58,
544 0xA5F8, 0x9EF0, 0x9830, 0x91C0, 0x8B90, 0x85A8, 0x8000, 0x7A90
548 #define LO_BYTE(v) ((v) & 0xff)
549 #define HI_BYTE(v) (((v) >> 8) & 0xff)
552 * Sets up the voice structure by calculating some values that
553 * will be needed later.
556 setup_voice(struct snd_emux_voice
*vp
)
558 struct soundfont_voice_parm
*parm
;
561 /* copy the original register values */
562 vp
->reg
= vp
->zone
->v
;
564 #ifdef SNDRV_EMUX_USE_RAW_EFFECT
565 snd_emux_setup_effect(vp
);
577 parm
= &vp
->reg
.parm
;
579 /* compute filter target and correct modulation parameters */
580 if (LO_BYTE(parm
->modatkhld
) >= 0x80 && parm
->moddelay
>= 0x8000) {
581 parm
->moddelay
= 0xbfff;
582 pitch
= (HI_BYTE(parm
->pefe
) << 4) + vp
->apitch
;
585 /* calculate filter target */
586 vp
->ftarget
= parm
->cutoff
+ LO_BYTE(parm
->pefe
);
587 LIMITVALUE(vp
->ftarget
, 0, 255);
590 vp
->ftarget
= parm
->cutoff
;
595 /* compute pitch target */
596 if (pitch
!= 0xffff) {
597 vp
->ptarget
= 1 << (pitch
>> 12);
598 if (pitch
& 0x800) vp
->ptarget
+= (vp
->ptarget
*0x102e)/0x2710;
599 if (pitch
& 0x400) vp
->ptarget
+= (vp
->ptarget
*0x764)/0x2710;
600 if (pitch
& 0x200) vp
->ptarget
+= (vp
->ptarget
*0x389)/0x2710;
601 vp
->ptarget
+= (vp
->ptarget
>> 1);
602 if (vp
->ptarget
> 0xffff) vp
->ptarget
= 0xffff;
604 vp
->ptarget
= 0xffff;
606 if (LO_BYTE(parm
->modatkhld
) >= 0x80) {
607 parm
->modatkhld
&= ~0xff;
608 parm
->modatkhld
|= 0x7f;
611 /* compute volume target and correct volume parameters */
613 #if 0 /* FIXME: this leads to some clicks.. */
614 if (LO_BYTE(parm
->volatkhld
) >= 0x80 && parm
->voldelay
>= 0x8000) {
615 parm
->voldelay
= 0xbfff;
616 vp
->vtarget
= voltarget
[vp
->avol
% 0x10] >> (vp
->avol
>> 4);
620 if (LO_BYTE(parm
->volatkhld
) >= 0x80) {
621 parm
->volatkhld
&= ~0xff;
622 parm
->volatkhld
|= 0x7f;
627 * calculate pitch parameter
629 static unsigned char pan_volumes
[256] = {
630 0x00,0x03,0x06,0x09,0x0c,0x0f,0x12,0x14,0x17,0x1a,0x1d,0x20,0x22,0x25,0x28,0x2a,
631 0x2d,0x30,0x32,0x35,0x37,0x3a,0x3c,0x3f,0x41,0x44,0x46,0x49,0x4b,0x4d,0x50,0x52,
632 0x54,0x57,0x59,0x5b,0x5d,0x60,0x62,0x64,0x66,0x68,0x6a,0x6c,0x6f,0x71,0x73,0x75,
633 0x77,0x79,0x7b,0x7c,0x7e,0x80,0x82,0x84,0x86,0x88,0x89,0x8b,0x8d,0x8f,0x90,0x92,
634 0x94,0x96,0x97,0x99,0x9a,0x9c,0x9e,0x9f,0xa1,0xa2,0xa4,0xa5,0xa7,0xa8,0xaa,0xab,
635 0xad,0xae,0xaf,0xb1,0xb2,0xb3,0xb5,0xb6,0xb7,0xb9,0xba,0xbb,0xbc,0xbe,0xbf,0xc0,
636 0xc1,0xc2,0xc3,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xcb,0xcc,0xcd,0xce,0xcf,0xd0,0xd1,
637 0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd7,0xd8,0xd9,0xda,0xdb,0xdc,0xdc,0xdd,0xde,0xdf,
638 0xdf,0xe0,0xe1,0xe2,0xe2,0xe3,0xe4,0xe4,0xe5,0xe6,0xe6,0xe7,0xe8,0xe8,0xe9,0xe9,
639 0xea,0xeb,0xeb,0xec,0xec,0xed,0xed,0xee,0xee,0xef,0xef,0xf0,0xf0,0xf1,0xf1,0xf1,
640 0xf2,0xf2,0xf3,0xf3,0xf3,0xf4,0xf4,0xf5,0xf5,0xf5,0xf6,0xf6,0xf6,0xf7,0xf7,0xf7,
641 0xf7,0xf8,0xf8,0xf8,0xf9,0xf9,0xf9,0xf9,0xf9,0xfa,0xfa,0xfa,0xfa,0xfb,0xfb,0xfb,
642 0xfb,0xfb,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,
643 0xfd,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,
644 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
645 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
649 calc_pan(struct snd_emux_voice
*vp
)
651 struct snd_midi_channel
*chan
= vp
->chan
;
654 /* pan & loop start (pan 8bit, MSB, 0:right, 0xff:left) */
655 if (vp
->reg
.fixpan
> 0) /* 0-127 */
656 pan
= 255 - (int)vp
->reg
.fixpan
* 2;
658 pan
= chan
->control
[MIDI_CTL_MSB_PAN
] - 64;
659 if (vp
->reg
.pan
>= 0) /* 0-127 */
660 pan
+= vp
->reg
.pan
- 64;
661 pan
= 127 - (int)pan
* 2;
663 LIMITVALUE(pan
, 0, 255);
665 if (vp
->emu
->linear_panning
) {
666 /* assuming linear volume */
667 if (pan
!= vp
->apan
) {
672 vp
->aaux
= (-pan
) & 0xff;
677 /* using volume table */
678 if (vp
->apan
!= (int)pan_volumes
[pan
]) {
679 vp
->apan
= pan_volumes
[pan
];
680 vp
->aaux
= pan_volumes
[255 - pan
];
689 * calculate volume attenuation
691 * Voice volume is controlled by volume attenuation parameter.
692 * So volume becomes maximum when avol is 0 (no attenuation), and
693 * minimum when 255 (-96dB or silence).
696 /* tables for volume->attenuation calculation */
697 static unsigned char voltab1
[128] = {
698 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
699 0x63, 0x2b, 0x29, 0x28, 0x27, 0x26, 0x25, 0x24, 0x23, 0x22,
700 0x21, 0x20, 0x1f, 0x1e, 0x1e, 0x1d, 0x1c, 0x1b, 0x1b, 0x1a,
701 0x19, 0x19, 0x18, 0x17, 0x17, 0x16, 0x16, 0x15, 0x15, 0x14,
702 0x14, 0x13, 0x13, 0x13, 0x12, 0x12, 0x11, 0x11, 0x11, 0x10,
703 0x10, 0x10, 0x0f, 0x0f, 0x0f, 0x0e, 0x0e, 0x0e, 0x0e, 0x0d,
704 0x0d, 0x0d, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0b, 0x0b, 0x0b,
705 0x0b, 0x0a, 0x0a, 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09,
706 0x08, 0x08, 0x08, 0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x06,
707 0x06, 0x06, 0x06, 0x06, 0x05, 0x05, 0x05, 0x05, 0x05, 0x04,
708 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02,
709 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01,
710 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
713 static unsigned char voltab2
[128] = {
714 0x32, 0x31, 0x30, 0x2f, 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x2a,
715 0x29, 0x28, 0x27, 0x26, 0x25, 0x24, 0x24, 0x23, 0x22, 0x21,
716 0x21, 0x20, 0x1f, 0x1e, 0x1e, 0x1d, 0x1c, 0x1c, 0x1b, 0x1a,
717 0x1a, 0x19, 0x19, 0x18, 0x18, 0x17, 0x16, 0x16, 0x15, 0x15,
718 0x14, 0x14, 0x13, 0x13, 0x13, 0x12, 0x12, 0x11, 0x11, 0x10,
719 0x10, 0x10, 0x0f, 0x0f, 0x0f, 0x0e, 0x0e, 0x0e, 0x0d, 0x0d,
720 0x0d, 0x0c, 0x0c, 0x0c, 0x0b, 0x0b, 0x0b, 0x0b, 0x0a, 0x0a,
721 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x08, 0x08, 0x08,
722 0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x07, 0x06, 0x06, 0x06,
723 0x06, 0x06, 0x06, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
724 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03,
725 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01,
726 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00
729 static unsigned char expressiontab
[128] = {
730 0x7f, 0x6c, 0x62, 0x5a, 0x54, 0x50, 0x4b, 0x48, 0x45, 0x42,
731 0x40, 0x3d, 0x3b, 0x39, 0x38, 0x36, 0x34, 0x33, 0x31, 0x30,
732 0x2f, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, 0x27, 0x26, 0x25,
733 0x24, 0x24, 0x23, 0x22, 0x21, 0x21, 0x20, 0x1f, 0x1e, 0x1e,
734 0x1d, 0x1d, 0x1c, 0x1b, 0x1b, 0x1a, 0x1a, 0x19, 0x18, 0x18,
735 0x17, 0x17, 0x16, 0x16, 0x15, 0x15, 0x15, 0x14, 0x14, 0x13,
736 0x13, 0x12, 0x12, 0x11, 0x11, 0x11, 0x10, 0x10, 0x0f, 0x0f,
737 0x0f, 0x0e, 0x0e, 0x0e, 0x0d, 0x0d, 0x0d, 0x0c, 0x0c, 0x0c,
738 0x0b, 0x0b, 0x0b, 0x0a, 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09,
739 0x08, 0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x06, 0x06, 0x06,
740 0x06, 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03,
741 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01,
742 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
746 * Magic to calculate the volume (actually attenuation) from all the
747 * voice and channels parameters.
750 calc_volume(struct snd_emux_voice
*vp
)
753 int main_vol
, expression_vol
, master_vol
;
754 struct snd_midi_channel
*chan
= vp
->chan
;
755 struct snd_emux_port
*port
= vp
->port
;
757 expression_vol
= chan
->control
[MIDI_CTL_MSB_EXPRESSION
];
758 LIMITMAX(vp
->velocity
, 127);
759 LIMITVALUE(expression_vol
, 0, 127);
760 if (port
->port_mode
== SNDRV_EMUX_PORT_MODE_OSS_SYNTH
) {
762 main_vol
= chan
->control
[MIDI_CTL_MSB_MAIN_VOLUME
];
763 vol
= (vp
->velocity
* main_vol
* expression_vol
) / (127*127);
764 vol
= vol
* vp
->reg
.amplitude
/ 127;
766 LIMITVALUE(vol
, 0, 127);
768 /* calc to attenuation */
769 vol
= snd_sf_vol_table
[vol
];
772 main_vol
= chan
->control
[MIDI_CTL_MSB_MAIN_VOLUME
] * vp
->reg
.amplitude
/ 127;
773 LIMITVALUE(main_vol
, 0, 127);
775 vol
= voltab1
[main_vol
] + voltab2
[vp
->velocity
];
777 vol
+= vp
->reg
.attenuation
;
778 vol
+= ((0x100 - vol
) * expressiontab
[expression_vol
])/128;
781 master_vol
= port
->chset
.gs_master_volume
;
782 LIMITVALUE(master_vol
, 0, 127);
783 vol
+= snd_sf_vol_table
[master_vol
];
784 vol
+= port
->volume_atten
;
786 #ifdef SNDRV_EMUX_USE_RAW_EFFECT
788 struct snd_emux_effect_table
*fx
= chan
->private;
789 vol
+= fx
->val
[EMUX_FX_ATTEN
];
793 LIMITVALUE(vol
, 0, 255);
795 return 0; /* value unchanged */
798 if (!SF_IS_DRUM_BANK(get_bank(port
, chan
))
799 && LO_BYTE(vp
->reg
.parm
.volatkhld
) < 0x7d) {
801 if (vp
->velocity
< 70)
804 atten
= vp
->velocity
;
805 vp
->acutoff
= (atten
* vp
->reg
.parm
.cutoff
+ 0xa0) >> 7;
807 vp
->acutoff
= vp
->reg
.parm
.cutoff
;
810 return 1; /* value changed */
814 * calculate pitch offset
816 * 0xE000 is no pitch offset at 44100Hz sample.
817 * Every 4096 is one octave.
821 calc_pitch(struct snd_emux_voice
*vp
)
823 struct snd_midi_channel
*chan
= vp
->chan
;
826 /* calculate offset */
827 if (vp
->reg
.fixkey
>= 0) {
828 offset
= (vp
->reg
.fixkey
- vp
->reg
.root
) * 4096 / 12;
830 offset
= (vp
->note
- vp
->reg
.root
) * 4096 / 12;
832 offset
= (offset
* vp
->reg
.scaleTuning
) / 100;
833 offset
+= vp
->reg
.tune
* 4096 / 1200;
834 if (chan
->midi_pitchbend
!= 0) {
835 /* (128 * 8192: 1 semitone) ==> (4096: 12 semitones) */
836 offset
+= chan
->midi_pitchbend
* chan
->gm_rpn_pitch_bend_range
/ 3072;
840 * coarse = -8192 to 8192 (100 cent per 128)
841 * fine = -8192 to 8192 (max=100cent)
843 /* 4096 = 1200 cents in emu8000 parameter */
844 offset
+= chan
->gm_rpn_coarse_tuning
* 4096 / (12 * 128);
845 offset
+= chan
->gm_rpn_fine_tuning
/ 24;
847 #ifdef SNDRV_EMUX_USE_RAW_EFFECT
848 /* add initial pitch correction */
850 struct snd_emux_effect_table
*fx
= chan
->private;
851 if (fx
->flag
[EMUX_FX_INIT_PITCH
])
852 offset
+= fx
->val
[EMUX_FX_INIT_PITCH
];
856 /* 0xe000: root pitch */
857 offset
+= 0xe000 + vp
->reg
.rate_offset
;
858 offset
+= vp
->emu
->pitch_shift
;
859 LIMITVALUE(offset
, 0, 0xffff);
860 if (offset
== vp
->apitch
)
861 return 0; /* unchanged */
863 return 1; /* value changed */
867 * Get the bank number assigned to the channel
870 get_bank(struct snd_emux_port
*port
, struct snd_midi_channel
*chan
)
874 switch (port
->chset
.midi_mode
) {
875 case SNDRV_MIDI_MODE_XG
:
876 val
= chan
->control
[MIDI_CTL_MSB_BANK
];
878 return 128; /* return drum bank */
879 return chan
->control
[MIDI_CTL_LSB_BANK
];
881 case SNDRV_MIDI_MODE_GS
:
882 if (chan
->drum_channel
)
884 /* ignore LSB (bank map) */
885 return chan
->control
[MIDI_CTL_MSB_BANK
];
888 if (chan
->drum_channel
)
890 return chan
->control
[MIDI_CTL_MSB_BANK
];
895 /* Look for the zones matching with the given note and velocity.
896 * The resultant zones are stored on table.
899 get_zone(struct snd_emux
*emu
, struct snd_emux_port
*port
,
900 int *notep
, int vel
, struct snd_midi_channel
*chan
,
901 struct snd_sf_zone
**table
)
903 int preset
, bank
, def_preset
, def_bank
;
905 bank
= get_bank(port
, chan
);
906 preset
= chan
->midi_program
;
908 if (SF_IS_DRUM_BANK(bank
)) {
909 def_preset
= port
->ctrls
[EMUX_MD_DEF_DRUM
];
913 def_bank
= port
->ctrls
[EMUX_MD_DEF_BANK
];
916 return snd_soundfont_search_zone(emu
->sflist
, notep
, vel
, preset
, bank
,
917 def_preset
, def_bank
,
918 table
, SNDRV_EMUX_MAX_MULTI_VOICES
);
924 snd_emux_init_voices(struct snd_emux
*emu
)
926 struct snd_emux_voice
*vp
;
930 spin_lock_irqsave(&emu
->voice_lock
, flags
);
931 for (i
= 0; i
< emu
->max_voices
; i
++) {
932 vp
= &emu
->voices
[i
];
933 vp
->ch
= -1; /* not used */
934 vp
->state
= SNDRV_EMUX_ST_OFF
;
941 spin_unlock_irqrestore(&emu
->voice_lock
, flags
);
946 void snd_emux_lock_voice(struct snd_emux
*emu
, int voice
)
950 spin_lock_irqsave(&emu
->voice_lock
, flags
);
951 if (emu
->voices
[voice
].state
== SNDRV_EMUX_ST_OFF
)
952 emu
->voices
[voice
].state
= SNDRV_EMUX_ST_LOCKED
;
954 snd_printk("invalid voice for lock %d (state = %x)\n",
955 voice
, emu
->voices
[voice
].state
);
956 spin_unlock_irqrestore(&emu
->voice_lock
, flags
);
959 EXPORT_SYMBOL(snd_emux_lock_voice
);
963 void snd_emux_unlock_voice(struct snd_emux
*emu
, int voice
)
967 spin_lock_irqsave(&emu
->voice_lock
, flags
);
968 if (emu
->voices
[voice
].state
== SNDRV_EMUX_ST_LOCKED
)
969 emu
->voices
[voice
].state
= SNDRV_EMUX_ST_OFF
;
971 snd_printk("invalid voice for unlock %d (state = %x)\n",
972 voice
, emu
->voices
[voice
].state
);
973 spin_unlock_irqrestore(&emu
->voice_lock
, flags
);
976 EXPORT_SYMBOL(snd_emux_unlock_voice
);