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