emux_synth.c revision fc20773329c993ec7d1b2c65618351f057d9d679
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		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->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}
962