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