blob: f13b038329ebfb29d5fad6728252484f162cb072 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * Midi synth routines for the Emu8k/Emu10k1
3 *
4 * Copyright (C) 1999 Steve Ratcliffe
5 * Copyright (c) 1999-2000 Takashi Iwai <tiwai@suse.de>
6 *
7 * Contains code based on awe_wave.c by Takashi Iwai
8 *
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.
13 *
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.
18 *
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
22 *
23 */
24
25#include "emux_voice.h"
26#include <sound/asoundef.h>
27
28/*
29 * Prototypes
30 */
31
32/*
33 * Ensure a value is between two points
34 * macro evaluates its args more than once, so changed to upper-case.
35 */
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)
38
39static 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);
40static int get_bank(snd_emux_port_t *port, snd_midi_channel_t *chan);
41static void terminate_note1(snd_emux_t *emu, int note, snd_midi_channel_t *chan, int free);
42static void exclusive_note_off(snd_emux_t *emu, snd_emux_port_t *port, int exclass);
43static void terminate_voice(snd_emux_t *emu, snd_emux_voice_t *vp, int free);
44static void update_voice(snd_emux_t *emu, snd_emux_voice_t *vp, int update);
45static void setup_voice(snd_emux_voice_t *vp);
46static int calc_pan(snd_emux_voice_t *vp);
47static int calc_volume(snd_emux_voice_t *vp);
48static int calc_pitch(snd_emux_voice_t *vp);
49
50
51/*
52 * Start a note.
53 */
54void
55snd_emux_note_on(void *p, int note, int vel, snd_midi_channel_t *chan)
56{
57 snd_emux_t *emu;
58 int i, key, nvoices;
59 snd_emux_voice_t *vp;
60 snd_sf_zone_t *table[SNDRV_EMUX_MAX_MULTI_VOICES];
61 unsigned long flags;
62 snd_emux_port_t *port;
63
64 port = p;
65 snd_assert(port != NULL && chan != NULL, return);
66
67 emu = port->emu;
68 snd_assert(emu != NULL, return);
69 snd_assert(emu->ops.get_voice != NULL, return);
70 snd_assert(emu->ops.trigger != NULL, return);
71
72 key = note; /* remember the original note */
73 nvoices = get_zone(emu, port, &note, vel, chan, table);
74 if (! nvoices)
75 return;
76
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);
82 }
83
84#if 0 // seems not necessary
85 /* Turn off the same note on the same channel. */
86 terminate_note1(emu, key, chan, 0);
87#endif
88
89 spin_lock_irqsave(&emu->voice_lock, flags);
90 for (i = 0; i < nvoices; i++) {
91
92 /* set up each voice parameter */
93 /* at this stage, we don't trigger the voice yet. */
94
95 if (table[i] == NULL)
96 continue;
97
98 vp = emu->ops.get_voice(emu, port);
99 if (vp == NULL || vp->ch < 0)
100 continue;
101 snd_assert(vp->emu != NULL && vp->hw != NULL, return);
102 if (STATE_IS_PLAYING(vp->state))
103 emu->ops.terminate(vp);
104
105 vp->time = emu->use_time++;
106 vp->chan = chan;
107 vp->port = port;
108 vp->key = key;
109 vp->note = note;
110 vp->velocity = vel;
111 vp->zone = table[i];
112 if (vp->zone->sample)
113 vp->block = vp->zone->sample->block;
114 else
115 vp->block = NULL;
116
117 setup_voice(vp);
118
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;
124 }
125 }
126
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 &&
131 vp->chan == chan) {
132 emu->ops.trigger(vp);
133 vp->state = SNDRV_EMUX_ST_ON;
134 vp->ontime = jiffies; /* remember the trigger timing */
135 }
136 }
137 spin_unlock_irqrestore(&emu->voice_lock, flags);
138
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;
143 if (fx) {
144 fx->flag[EMUX_FX_SAMPLE_START] = 0;
145 fx->flag[EMUX_FX_COARSE_SAMPLE_START] = 0;
146 }
147 }
148#endif
149}
150
151/*
152 * Release a note in response to a midi note off.
153 */
154void
155snd_emux_note_off(void *p, int note, int vel, snd_midi_channel_t *chan)
156{
157 int ch;
158 snd_emux_t *emu;
159 snd_emux_voice_t *vp;
160 unsigned long flags;
161 snd_emux_port_t *port;
162
163 port = p;
164 snd_assert(port != NULL && chan != NULL, return);
165
166 emu = port->emu;
167 snd_assert(emu != NULL, return);
168 snd_assert(emu->ops.release != NULL, return);
169
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.
182 */
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;
188 }
189 } else
190 /* ok now release the note */
191 emu->ops.release(vp);
192 }
193 }
194 spin_unlock_irqrestore(&emu->voice_lock, flags);
195}
196
197/*
198 * timer callback
199 *
200 * release the pending note-offs
201 */
202void snd_emux_timer_callback(unsigned long data)
203{
204 snd_emux_t *emu = (snd_emux_t*) data;
205 snd_emux_voice_t *vp;
206 int ch, do_again = 0;
207
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 */
214 else {
215 emu->ops.release(vp);
216 vp->state = SNDRV_EMUX_ST_RELEASED;
217 }
218 }
219 }
220 if (do_again) {
221 emu->tlist.expires = jiffies + 1;
222 add_timer(&emu->tlist);
223 emu->timer_active = 1;
224 } else
225 emu->timer_active = 0;
226 spin_unlock(&emu->voice_lock);
227}
228
229/*
230 * key pressure change
231 */
232void
233snd_emux_key_press(void *p, int note, int vel, snd_midi_channel_t *chan)
234{
235 int ch;
236 snd_emux_t *emu;
237 snd_emux_voice_t *vp;
238 unsigned long flags;
239 snd_emux_port_t *port;
240
241 port = p;
242 snd_assert(port != NULL && chan != NULL, return);
243
244 emu = port->emu;
245 snd_assert(emu != NULL, return);
246 snd_assert(emu->ops.update != NULL, return);
247
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) {
253 vp->velocity = vel;
254 update_voice(emu, vp, SNDRV_EMUX_UPDATE_VOLUME);
255 }
256 }
257 spin_unlock_irqrestore(&emu->voice_lock, flags);
258}
259
260
261/*
262 * Modulate the voices which belong to the channel
263 */
264void
265snd_emux_update_channel(snd_emux_port_t *port, snd_midi_channel_t *chan, int update)
266{
267 snd_emux_t *emu;
268 snd_emux_voice_t *vp;
269 int i;
270 unsigned long flags;
271
272 if (! update)
273 return;
274
275 emu = port->emu;
276 snd_assert(emu != NULL, return);
277 snd_assert(emu->ops.update != NULL, return);
278
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);
284 }
285 spin_unlock_irqrestore(&emu->voice_lock, flags);
286}
287
288/*
289 * Modulate all the voices which belong to the port.
290 */
291void
292snd_emux_update_port(snd_emux_port_t *port, int update)
293{
294 snd_emux_t *emu;
295 snd_emux_voice_t *vp;
296 int i;
297 unsigned long flags;
298
299 if (! update)
300 return;
301
302 emu = port->emu;
303 snd_assert(emu != NULL, return);
304 snd_assert(emu->ops.update != NULL, return);
305
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);
311 }
312 spin_unlock_irqrestore(&emu->voice_lock, flags);
313}
314
315
316/*
317 * Deal with a controler type event. This includes all types of
318 * control events, not just the midi controllers
319 */
320void
321snd_emux_control(void *p, int type, snd_midi_channel_t *chan)
322{
323 snd_emux_port_t *port;
324
325 port = p;
326 snd_assert(port != NULL && chan != NULL, return);
327
328 switch (type) {
329 case MIDI_CTL_MSB_MAIN_VOLUME:
330 case MIDI_CTL_MSB_EXPRESSION:
331 snd_emux_update_channel(port, chan, SNDRV_EMUX_UPDATE_VOLUME);
332 break;
333
334 case MIDI_CTL_MSB_PAN:
335 snd_emux_update_channel(port, chan, SNDRV_EMUX_UPDATE_PAN);
336 break;
337
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,
342 EMUX_FX_FLAG_ADD);
343#endif
344 break;
345
346 case MIDI_CTL_PITCHBEND:
347 snd_emux_update_channel(port, chan, SNDRV_EMUX_UPDATE_PITCH);
348 break;
349
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);
355 break;
356
357 }
358
359 if (port->chset.midi_mode == SNDRV_MIDI_MODE_XG) {
360 snd_emux_xg_control(port, chan, type);
361 }
362}
363
364
365/*
366 * terminate note - if free flag is true, free the terminated voice
367 */
368static void
369terminate_note1(snd_emux_t *emu, int note, snd_midi_channel_t *chan, int free)
370{
371 int i;
372 snd_emux_voice_t *vp;
373 unsigned long flags;
374
375 spin_lock_irqsave(&emu->voice_lock, flags);
376 for (i = 0; i < emu->max_voices; i++) {
377 vp = &emu->voices[i];
378 if (STATE_IS_PLAYING(vp->state) && vp->chan == chan &&
379 vp->key == note)
380 terminate_voice(emu, vp, free);
381 }
382 spin_unlock_irqrestore(&emu->voice_lock, flags);
383}
384
385
386/*
387 * terminate note - exported for midi emulation
388 */
389void
390snd_emux_terminate_note(void *p, int note, snd_midi_channel_t *chan)
391{
392 snd_emux_t *emu;
393 snd_emux_port_t *port;
394
395 port = p;
396 snd_assert(port != NULL && chan != NULL, return);
397
398 emu = port->emu;
399 snd_assert(emu != NULL, return);
400 snd_assert(emu->ops.terminate != NULL, return);
401
402 terminate_note1(emu, note, chan, 1);
403}
404
405
406/*
407 * Terminate all the notes
408 */
409void
410snd_emux_terminate_all(snd_emux_t *emu)
411{
412 int i;
413 snd_emux_voice_t *vp;
414 unsigned long flags;
415
416 spin_lock_irqsave(&emu->voice_lock, flags);
417 for (i = 0; i < emu->max_voices; i++) {
418 vp = &emu->voices[i];
419 if (STATE_IS_PLAYING(vp->state))
420 terminate_voice(emu, vp, 0);
421 if (vp->state == SNDRV_EMUX_ST_OFF) {
422 if (emu->ops.free_voice)
423 emu->ops.free_voice(vp);
424 if (emu->ops.reset)
425 emu->ops.reset(emu, i);
426 }
427 vp->time = 0;
428 }
429 /* initialize allocation time */
430 emu->use_time = 0;
431 spin_unlock_irqrestore(&emu->voice_lock, flags);
432}
433
434
435/*
436 * Terminate all voices associated with the given port
437 */
438void
439snd_emux_sounds_off_all(snd_emux_port_t *port)
440{
441 int i;
442 snd_emux_t *emu;
443 snd_emux_voice_t *vp;
444 unsigned long flags;
445
446 snd_assert(port != NULL, return);
447 emu = port->emu;
448 snd_assert(emu != NULL, return);
449 snd_assert(emu->ops.terminate != NULL, return);
450
451 spin_lock_irqsave(&emu->voice_lock, flags);
452 for (i = 0; i < emu->max_voices; i++) {
453 vp = &emu->voices[i];
454 if (STATE_IS_PLAYING(vp->state) &&
455 vp->port == port)
456 terminate_voice(emu, vp, 0);
457 if (vp->state == SNDRV_EMUX_ST_OFF) {
458 if (emu->ops.free_voice)
459 emu->ops.free_voice(vp);
460 if (emu->ops.reset)
461 emu->ops.reset(emu, i);
462 }
463 }
464 spin_unlock_irqrestore(&emu->voice_lock, flags);
465}
466
467
468/*
469 * Terminate all voices that have the same exclusive class. This
470 * is mainly for drums.
471 */
472static void
473exclusive_note_off(snd_emux_t *emu, snd_emux_port_t *port, int exclass)
474{
475 snd_emux_voice_t *vp;
476 int i;
477 unsigned long flags;
478
479 spin_lock_irqsave(&emu->voice_lock, flags);
480 for (i = 0; i < emu->max_voices; i++) {
481 vp = &emu->voices[i];
482 if (STATE_IS_PLAYING(vp->state) && vp->port == port &&
483 vp->reg.exclusiveClass == exclass) {
484 terminate_voice(emu, vp, 0);
485 }
486 }
487 spin_unlock_irqrestore(&emu->voice_lock, flags);
488}
489
490/*
491 * terminate a voice
492 * if free flag is true, call free_voice after termination
493 */
494static void
495terminate_voice(snd_emux_t *emu, snd_emux_voice_t *vp, int free)
496{
497 emu->ops.terminate(vp);
498 vp->time = emu->use_time++;
499 vp->chan = NULL;
500 vp->port = NULL;
501 vp->zone = NULL;
502 vp->block = NULL;
503 vp->state = SNDRV_EMUX_ST_OFF;
504 if (free && emu->ops.free_voice)
505 emu->ops.free_voice(vp);
506}
507
508
509/*
510 * Modulate the voice
511 */
512static void
513update_voice(snd_emux_t *emu, snd_emux_voice_t *vp, int update)
514{
515 if (!STATE_IS_PLAYING(vp->state))
516 return;
517
518 if (vp->chan == NULL || vp->port == NULL)
519 return;
520 if (update & SNDRV_EMUX_UPDATE_VOLUME)
521 calc_volume(vp);
522 if (update & SNDRV_EMUX_UPDATE_PITCH)
523 calc_pitch(vp);
524 if (update & SNDRV_EMUX_UPDATE_PAN) {
525 if (! calc_pan(vp) && (update == SNDRV_EMUX_UPDATE_PAN))
526 return;
527 }
528 emu->ops.update(vp, update);
529}
530
531
532#if 0 // not used
533/* table for volume target calculation */
534static unsigned short voltarget[16] = {
535 0xEAC0, 0xE0C8, 0xD740, 0xCE20, 0xC560, 0xBD08, 0xB500, 0xAD58,
536 0xA5F8, 0x9EF0, 0x9830, 0x91C0, 0x8B90, 0x85A8, 0x8000, 0x7A90
537};
538#endif
539
540#define LO_BYTE(v) ((v) & 0xff)
541#define HI_BYTE(v) (((v) >> 8) & 0xff)
542
543/*
544 * Sets up the voice structure by calculating some values that
545 * will be needed later.
546 */
547static void
548setup_voice(snd_emux_voice_t *vp)
549{
550 soundfont_voice_parm_t *parm;
551 int pitch;
552
553 /* copy the original register values */
554 vp->reg = vp->zone->v;
555
556#ifdef SNDRV_EMUX_USE_RAW_EFFECT
557 snd_emux_setup_effect(vp);
558#endif
559
560 /* reset status */
561 vp->apan = -1;
562 vp->avol = -1;
563 vp->apitch = -1;
564
565 calc_volume(vp);
566 calc_pitch(vp);
567 calc_pan(vp);
568
569 parm = &vp->reg.parm;
570
571 /* compute filter target and correct modulation parameters */
572 if (LO_BYTE(parm->modatkhld) >= 0x80 && parm->moddelay >= 0x8000) {
573 parm->moddelay = 0xbfff;
574 pitch = (HI_BYTE(parm->pefe) << 4) + vp->apitch;
575 if (pitch > 0xffff)
576 pitch = 0xffff;
577 /* calculate filter target */
578 vp->ftarget = parm->cutoff + LO_BYTE(parm->pefe);
579 LIMITVALUE(vp->ftarget, 0, 255);
580 vp->ftarget <<= 8;
581 } else {
582 vp->ftarget = parm->cutoff;
583 vp->ftarget <<= 8;
584 pitch = vp->apitch;
585 }
586
587 /* compute pitch target */
588 if (pitch != 0xffff) {
589 vp->ptarget = 1 << (pitch >> 12);
590 if (pitch & 0x800) vp->ptarget += (vp->ptarget*0x102e)/0x2710;
591 if (pitch & 0x400) vp->ptarget += (vp->ptarget*0x764)/0x2710;
592 if (pitch & 0x200) vp->ptarget += (vp->ptarget*0x389)/0x2710;
593 vp->ptarget += (vp->ptarget >> 1);
594 if (vp->ptarget > 0xffff) vp->ptarget = 0xffff;
595 } else
596 vp->ptarget = 0xffff;
597
598 if (LO_BYTE(parm->modatkhld) >= 0x80) {
599 parm->modatkhld &= ~0xff;
600 parm->modatkhld |= 0x7f;
601 }
602
603 /* compute volume target and correct volume parameters */
604 vp->vtarget = 0;
605#if 0 /* FIXME: this leads to some clicks.. */
606 if (LO_BYTE(parm->volatkhld) >= 0x80 && parm->voldelay >= 0x8000) {
607 parm->voldelay = 0xbfff;
608 vp->vtarget = voltarget[vp->avol % 0x10] >> (vp->avol >> 4);
609 }
610#endif
611
612 if (LO_BYTE(parm->volatkhld) >= 0x80) {
613 parm->volatkhld &= ~0xff;
614 parm->volatkhld |= 0x7f;
615 }
616}
617
618/*
619 * calculate pitch parameter
620 */
621static unsigned char pan_volumes[256] = {
6220x00,0x03,0x06,0x09,0x0c,0x0f,0x12,0x14,0x17,0x1a,0x1d,0x20,0x22,0x25,0x28,0x2a,
6230x2d,0x30,0x32,0x35,0x37,0x3a,0x3c,0x3f,0x41,0x44,0x46,0x49,0x4b,0x4d,0x50,0x52,
6240x54,0x57,0x59,0x5b,0x5d,0x60,0x62,0x64,0x66,0x68,0x6a,0x6c,0x6f,0x71,0x73,0x75,
6250x77,0x79,0x7b,0x7c,0x7e,0x80,0x82,0x84,0x86,0x88,0x89,0x8b,0x8d,0x8f,0x90,0x92,
6260x94,0x96,0x97,0x99,0x9a,0x9c,0x9e,0x9f,0xa1,0xa2,0xa4,0xa5,0xa7,0xa8,0xaa,0xab,
6270xad,0xae,0xaf,0xb1,0xb2,0xb3,0xb5,0xb6,0xb7,0xb9,0xba,0xbb,0xbc,0xbe,0xbf,0xc0,
6280xc1,0xc2,0xc3,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xcb,0xcc,0xcd,0xce,0xcf,0xd0,0xd1,
6290xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd7,0xd8,0xd9,0xda,0xdb,0xdc,0xdc,0xdd,0xde,0xdf,
6300xdf,0xe0,0xe1,0xe2,0xe2,0xe3,0xe4,0xe4,0xe5,0xe6,0xe6,0xe7,0xe8,0xe8,0xe9,0xe9,
6310xea,0xeb,0xeb,0xec,0xec,0xed,0xed,0xee,0xee,0xef,0xef,0xf0,0xf0,0xf1,0xf1,0xf1,
6320xf2,0xf2,0xf3,0xf3,0xf3,0xf4,0xf4,0xf5,0xf5,0xf5,0xf6,0xf6,0xf6,0xf7,0xf7,0xf7,
6330xf7,0xf8,0xf8,0xf8,0xf9,0xf9,0xf9,0xf9,0xf9,0xfa,0xfa,0xfa,0xfa,0xfb,0xfb,0xfb,
6340xfb,0xfb,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,
6350xfd,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,
6360xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
6370xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
638};
639
640static int
641calc_pan(snd_emux_voice_t *vp)
642{
643 snd_midi_channel_t *chan = vp->chan;
644 int pan;
645
646 /* pan & loop start (pan 8bit, MSB, 0:right, 0xff:left) */
647 if (vp->reg.fixpan > 0) /* 0-127 */
648 pan = 255 - (int)vp->reg.fixpan * 2;
649 else {
650 pan = chan->control[MIDI_CTL_MSB_PAN] - 64;
651 if (vp->reg.pan >= 0) /* 0-127 */
652 pan += vp->reg.pan - 64;
653 pan = 127 - (int)pan * 2;
654 }
655 LIMITVALUE(pan, 0, 255);
656
657 if (vp->emu->linear_panning) {
658 /* assuming linear volume */
659 if (pan != vp->apan) {
660 vp->apan = pan;
661 if (pan == 0)
662 vp->aaux = 0xff;
663 else
664 vp->aaux = (-pan) & 0xff;
665 return 1;
666 } else
667 return 0;
668 } else {
669 /* using volume table */
670 if (vp->apan != (int)pan_volumes[pan]) {
671 vp->apan = pan_volumes[pan];
672 vp->aaux = pan_volumes[255 - pan];
673 return 1;
674 }
675 return 0;
676 }
677}
678
679
680/*
681 * calculate volume attenuation
682 *
683 * Voice volume is controlled by volume attenuation parameter.
684 * So volume becomes maximum when avol is 0 (no attenuation), and
685 * minimum when 255 (-96dB or silence).
686 */
687
688/* tables for volume->attenuation calculation */
689static unsigned char voltab1[128] = {
690 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
691 0x63, 0x2b, 0x29, 0x28, 0x27, 0x26, 0x25, 0x24, 0x23, 0x22,
692 0x21, 0x20, 0x1f, 0x1e, 0x1e, 0x1d, 0x1c, 0x1b, 0x1b, 0x1a,
693 0x19, 0x19, 0x18, 0x17, 0x17, 0x16, 0x16, 0x15, 0x15, 0x14,
694 0x14, 0x13, 0x13, 0x13, 0x12, 0x12, 0x11, 0x11, 0x11, 0x10,
695 0x10, 0x10, 0x0f, 0x0f, 0x0f, 0x0e, 0x0e, 0x0e, 0x0e, 0x0d,
696 0x0d, 0x0d, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0b, 0x0b, 0x0b,
697 0x0b, 0x0a, 0x0a, 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09,
698 0x08, 0x08, 0x08, 0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x06,
699 0x06, 0x06, 0x06, 0x06, 0x05, 0x05, 0x05, 0x05, 0x05, 0x04,
700 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02,
701 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01,
702 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
703};
704
705static unsigned char voltab2[128] = {
706 0x32, 0x31, 0x30, 0x2f, 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x2a,
707 0x29, 0x28, 0x27, 0x26, 0x25, 0x24, 0x24, 0x23, 0x22, 0x21,
708 0x21, 0x20, 0x1f, 0x1e, 0x1e, 0x1d, 0x1c, 0x1c, 0x1b, 0x1a,
709 0x1a, 0x19, 0x19, 0x18, 0x18, 0x17, 0x16, 0x16, 0x15, 0x15,
710 0x14, 0x14, 0x13, 0x13, 0x13, 0x12, 0x12, 0x11, 0x11, 0x10,
711 0x10, 0x10, 0x0f, 0x0f, 0x0f, 0x0e, 0x0e, 0x0e, 0x0d, 0x0d,
712 0x0d, 0x0c, 0x0c, 0x0c, 0x0b, 0x0b, 0x0b, 0x0b, 0x0a, 0x0a,
713 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x08, 0x08, 0x08,
714 0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x07, 0x06, 0x06, 0x06,
715 0x06, 0x06, 0x06, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
716 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03,
717 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01,
718 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00
719};
720
721static unsigned char expressiontab[128] = {
722 0x7f, 0x6c, 0x62, 0x5a, 0x54, 0x50, 0x4b, 0x48, 0x45, 0x42,
723 0x40, 0x3d, 0x3b, 0x39, 0x38, 0x36, 0x34, 0x33, 0x31, 0x30,
724 0x2f, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, 0x27, 0x26, 0x25,
725 0x24, 0x24, 0x23, 0x22, 0x21, 0x21, 0x20, 0x1f, 0x1e, 0x1e,
726 0x1d, 0x1d, 0x1c, 0x1b, 0x1b, 0x1a, 0x1a, 0x19, 0x18, 0x18,
727 0x17, 0x17, 0x16, 0x16, 0x15, 0x15, 0x15, 0x14, 0x14, 0x13,
728 0x13, 0x12, 0x12, 0x11, 0x11, 0x11, 0x10, 0x10, 0x0f, 0x0f,
729 0x0f, 0x0e, 0x0e, 0x0e, 0x0d, 0x0d, 0x0d, 0x0c, 0x0c, 0x0c,
730 0x0b, 0x0b, 0x0b, 0x0a, 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09,
731 0x08, 0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x06, 0x06, 0x06,
732 0x06, 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03,
733 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01,
734 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
735};
736
737/*
738 * Magic to calculate the volume (actually attenuation) from all the
739 * voice and channels parameters.
740 */
741static int
742calc_volume(snd_emux_voice_t *vp)
743{
744 int vol;
745 int main_vol, expression_vol, master_vol;
746 snd_midi_channel_t *chan = vp->chan;
747 snd_emux_port_t *port = vp->port;
748
749 expression_vol = chan->control[MIDI_CTL_MSB_EXPRESSION];
750 LIMITMAX(vp->velocity, 127);
751 LIMITVALUE(expression_vol, 0, 127);
752 if (port->port_mode == SNDRV_EMUX_PORT_MODE_OSS_SYNTH) {
753 /* 0 - 127 */
754 main_vol = chan->control[MIDI_CTL_MSB_MAIN_VOLUME];
755 vol = (vp->velocity * main_vol * expression_vol) / (127*127);
756 vol = vol * vp->reg.amplitude / 127;
757
758 LIMITVALUE(vol, 0, 127);
759
760 /* calc to attenuation */
761 vol = snd_sf_vol_table[vol];
762
763 } else {
764 main_vol = chan->control[MIDI_CTL_MSB_MAIN_VOLUME] * vp->reg.amplitude / 127;
765 LIMITVALUE(main_vol, 0, 127);
766
767 vol = voltab1[main_vol] + voltab2[vp->velocity];
768 vol = (vol * 8) / 3;
769 vol += vp->reg.attenuation;
770 vol += ((0x100 - vol) * expressiontab[expression_vol])/128;
771 }
772
773 master_vol = port->chset.gs_master_volume;
774 LIMITVALUE(master_vol, 0, 127);
775 vol += snd_sf_vol_table[master_vol];
776 vol += port->volume_atten;
777
778#ifdef SNDRV_EMUX_USE_RAW_EFFECT
779 if (chan->private) {
780 snd_emux_effect_table_t *fx = chan->private;
781 vol += fx->val[EMUX_FX_ATTEN];
782 }
783#endif
784
785 LIMITVALUE(vol, 0, 255);
786 if (vp->avol == vol)
787 return 0; /* value unchanged */
788
789 vp->avol = vol;
790 if (!SF_IS_DRUM_BANK(get_bank(port, chan))
791 && LO_BYTE(vp->reg.parm.volatkhld) < 0x7d) {
792 int atten;
793 if (vp->velocity < 70)
794 atten = 70;
795 else
796 atten = vp->velocity;
797 vp->acutoff = (atten * vp->reg.parm.cutoff + 0xa0) >> 7;
798 } else {
799 vp->acutoff = vp->reg.parm.cutoff;
800 }
801
802 return 1; /* value changed */
803}
804
805/*
806 * calculate pitch offset
807 *
808 * 0xE000 is no pitch offset at 44100Hz sample.
809 * Every 4096 is one octave.
810 */
811
812static int
813calc_pitch(snd_emux_voice_t *vp)
814{
815 snd_midi_channel_t *chan = vp->chan;
816 int offset;
817
818 /* calculate offset */
819 if (vp->reg.fixkey >= 0) {
820 offset = (vp->reg.fixkey - vp->reg.root) * 4096 / 12;
821 } else {
822 offset = (vp->note - vp->reg.root) * 4096 / 12;
823 }
824 offset = (offset * vp->reg.scaleTuning) / 100;
825 offset += vp->reg.tune * 4096 / 1200;
826 if (chan->midi_pitchbend != 0) {
827 /* (128 * 8192: 1 semitone) ==> (4096: 12 semitones) */
828 offset += chan->midi_pitchbend * chan->gm_rpn_pitch_bend_range / 3072;
829 }
830
831 /* tuning via RPN:
832 * coarse = -8192 to 8192 (100 cent per 128)
833 * fine = -8192 to 8192 (max=100cent)
834 */
835 /* 4096 = 1200 cents in emu8000 parameter */
836 offset += chan->gm_rpn_coarse_tuning * 4096 / (12 * 128);
837 offset += chan->gm_rpn_fine_tuning / 24;
838
839#ifdef SNDRV_EMUX_USE_RAW_EFFECT
840 /* add initial pitch correction */
841 if (chan->private) {
842 snd_emux_effect_table_t *fx = chan->private;
843 if (fx->flag[EMUX_FX_INIT_PITCH])
844 offset += fx->val[EMUX_FX_INIT_PITCH];
845 }
846#endif
847
848 /* 0xe000: root pitch */
849 offset += 0xe000 + vp->reg.rate_offset;
850 offset += vp->emu->pitch_shift;
851 LIMITVALUE(offset, 0, 0xffff);
852 if (offset == vp->apitch)
853 return 0; /* unchanged */
854 vp->apitch = offset;
855 return 1; /* value changed */
856}
857
858/*
859 * Get the bank number assigned to the channel
860 */
861static int
862get_bank(snd_emux_port_t *port, snd_midi_channel_t *chan)
863{
864 int val;
865
866 switch (port->chset.midi_mode) {
867 case SNDRV_MIDI_MODE_XG:
868 val = chan->control[MIDI_CTL_MSB_BANK];
869 if (val == 127)
870 return 128; /* return drum bank */
871 return chan->control[MIDI_CTL_LSB_BANK];
872
873 case SNDRV_MIDI_MODE_GS:
874 if (chan->drum_channel)
875 return 128;
876 /* ignore LSB (bank map) */
877 return chan->control[MIDI_CTL_MSB_BANK];
878
879 default:
880 if (chan->drum_channel)
881 return 128;
882 return chan->control[MIDI_CTL_MSB_BANK];
883 }
884}
885
886
887/* Look for the zones matching with the given note and velocity.
888 * The resultant zones are stored on table.
889 */
890static int
891get_zone(snd_emux_t *emu, snd_emux_port_t *port,
892 int *notep, int vel, snd_midi_channel_t *chan, snd_sf_zone_t **table)
893{
894 int preset, bank, def_preset, def_bank;
895
896 bank = get_bank(port, chan);
897 preset = chan->midi_program;
898
899 if (SF_IS_DRUM_BANK(bank)) {
900 def_preset = port->ctrls[EMUX_MD_DEF_DRUM];
901 def_bank = bank;
902 } else {
903 def_preset = preset;
904 def_bank = port->ctrls[EMUX_MD_DEF_BANK];
905 }
906
907 return snd_soundfont_search_zone(emu->sflist, notep, vel, preset, bank,
908 def_preset, def_bank,
909 table, SNDRV_EMUX_MAX_MULTI_VOICES);
910}
911
912/*
913 */
914void
915snd_emux_init_voices(snd_emux_t *emu)
916{
917 snd_emux_voice_t *vp;
918 int i;
919 unsigned long flags;
920
921 spin_lock_irqsave(&emu->voice_lock, flags);
922 for (i = 0; i < emu->max_voices; i++) {
923 vp = &emu->voices[i];
924 vp->ch = -1; /* not used */
925 vp->state = SNDRV_EMUX_ST_OFF;
926 vp->chan = NULL;
927 vp->port = NULL;
928 vp->time = 0;
929 vp->emu = emu;
930 vp->hw = emu->hw;
931 }
932 spin_unlock_irqrestore(&emu->voice_lock, flags);
933}
934
935/*
936 */
937void snd_emux_lock_voice(snd_emux_t *emu, int voice)
938{
939 unsigned long flags;
940
941 spin_lock_irqsave(&emu->voice_lock, flags);
942 if (emu->voices[voice].state == SNDRV_EMUX_ST_OFF)
943 emu->voices[voice].state = SNDRV_EMUX_ST_LOCKED;
944 else
945 snd_printk("invalid voice for lock %d (state = %x)\n",
946 voice, emu->voices[voice].state);
947 spin_unlock_irqrestore(&emu->voice_lock, flags);
948}
949
950/*
951 */
952void snd_emux_unlock_voice(snd_emux_t *emu, int voice)
953{
954 unsigned long flags;
955
956 spin_lock_irqsave(&emu->voice_lock, flags);
957 if (emu->voices[voice].state == SNDRV_EMUX_ST_LOCKED)
958 emu->voices[voice].state = SNDRV_EMUX_ST_OFF;
959 else
960 snd_printk("invalid voice for unlock %d (state = %x)\n",
961 voice, emu->voices[voice].state);
962 spin_unlock_irqrestore(&emu->voice_lock, flags);
963}