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