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