emux_synth.c revision 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2
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
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}
964