cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

emux_synth.c (25333B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 *  Midi synth routines for the Emu8k/Emu10k1
      4 *
      5 *  Copyright (C) 1999 Steve Ratcliffe
      6 *  Copyright (c) 1999-2000 Takashi Iwai <tiwai@suse.de>
      7 *
      8 *  Contains code based on awe_wave.c by Takashi Iwai
      9 */
     10
     11#include <linux/export.h>
     12#include "emux_voice.h"
     13#include <sound/asoundef.h>
     14
     15/*
     16 * Prototypes
     17 */
     18
     19/*
     20 * Ensure a value is between two points
     21 * macro evaluates its args more than once, so changed to upper-case.
     22 */
     23#define LIMITVALUE(x, a, b) do { if ((x) < (a)) (x) = (a); else if ((x) > (b)) (x) = (b); } while (0)
     24#define LIMITMAX(x, a) do {if ((x) > (a)) (x) = (a); } while (0)
     25
     26static int get_zone(struct snd_emux *emu, struct snd_emux_port *port,
     27		    int *notep, int vel, struct snd_midi_channel *chan,
     28		    struct snd_sf_zone **table);
     29static int get_bank(struct snd_emux_port *port, struct snd_midi_channel *chan);
     30static void terminate_note1(struct snd_emux *emu, int note,
     31			    struct snd_midi_channel *chan, int free);
     32static void exclusive_note_off(struct snd_emux *emu, struct snd_emux_port *port,
     33			       int exclass);
     34static void terminate_voice(struct snd_emux *emu, struct snd_emux_voice *vp, int free);
     35static void update_voice(struct snd_emux *emu, struct snd_emux_voice *vp, int update);
     36static void setup_voice(struct snd_emux_voice *vp);
     37static int calc_pan(struct snd_emux_voice *vp);
     38static int calc_volume(struct snd_emux_voice *vp);
     39static int calc_pitch(struct snd_emux_voice *vp);
     40
     41
     42/*
     43 * Start a note.
     44 */
     45void
     46snd_emux_note_on(void *p, int note, int vel, struct snd_midi_channel *chan)
     47{
     48	struct snd_emux *emu;
     49	int i, key, nvoices;
     50	struct snd_emux_voice *vp;
     51	struct snd_sf_zone *table[SNDRV_EMUX_MAX_MULTI_VOICES];
     52	unsigned long flags;
     53	struct snd_emux_port *port;
     54
     55	port = p;
     56	if (snd_BUG_ON(!port || !chan))
     57		return;
     58
     59	emu = port->emu;
     60	if (snd_BUG_ON(!emu || !emu->ops.get_voice || !emu->ops.trigger))
     61		return;
     62
     63	key = note; /* remember the original note */
     64	nvoices = get_zone(emu, port, &note, vel, chan, table);
     65	if (! nvoices)
     66		return;
     67
     68	/* exclusive note off */
     69	for (i = 0; i < nvoices; i++) {
     70		struct snd_sf_zone *zp = table[i];
     71		if (zp && zp->v.exclusiveClass)
     72			exclusive_note_off(emu, port, zp->v.exclusiveClass);
     73	}
     74
     75#if 0 // seems not necessary
     76	/* Turn off the same note on the same channel. */
     77	terminate_note1(emu, key, chan, 0);
     78#endif
     79
     80	spin_lock_irqsave(&emu->voice_lock, flags);
     81	for (i = 0; i < nvoices; i++) {
     82
     83		/* set up each voice parameter */
     84		/* at this stage, we don't trigger the voice yet. */
     85
     86		if (table[i] == NULL)
     87			continue;
     88
     89		vp = emu->ops.get_voice(emu, port);
     90		if (vp == NULL || vp->ch < 0)
     91			continue;
     92		if (STATE_IS_PLAYING(vp->state))
     93			emu->ops.terminate(vp);
     94
     95		vp->time = emu->use_time++;
     96		vp->chan = chan;
     97		vp->port = port;
     98		vp->key = key;
     99		vp->note = note;
    100		vp->velocity = vel;
    101		vp->zone = table[i];
    102		if (vp->zone->sample)
    103			vp->block = vp->zone->sample->block;
    104		else
    105			vp->block = NULL;
    106
    107		setup_voice(vp);
    108
    109		vp->state = SNDRV_EMUX_ST_STANDBY;
    110		if (emu->ops.prepare) {
    111			vp->state = SNDRV_EMUX_ST_OFF;
    112			if (emu->ops.prepare(vp) >= 0)
    113				vp->state = SNDRV_EMUX_ST_STANDBY;
    114		}
    115	}
    116
    117	/* start envelope now */
    118	for (i = 0; i < emu->max_voices; i++) {
    119		vp = &emu->voices[i];
    120		if (vp->state == SNDRV_EMUX_ST_STANDBY &&
    121		    vp->chan == chan) {
    122			emu->ops.trigger(vp);
    123			vp->state = SNDRV_EMUX_ST_ON;
    124			vp->ontime = jiffies; /* remember the trigger timing */
    125		}
    126	}
    127	spin_unlock_irqrestore(&emu->voice_lock, flags);
    128
    129#ifdef SNDRV_EMUX_USE_RAW_EFFECT
    130	if (port->port_mode == SNDRV_EMUX_PORT_MODE_OSS_SYNTH) {
    131		/* clear voice position for the next note on this channel */
    132		struct snd_emux_effect_table *fx = chan->private;
    133		if (fx) {
    134			fx->flag[EMUX_FX_SAMPLE_START] = 0;
    135			fx->flag[EMUX_FX_COARSE_SAMPLE_START] = 0;
    136		}
    137	}
    138#endif
    139}
    140
    141/*
    142 * Release a note in response to a midi note off.
    143 */
    144void
    145snd_emux_note_off(void *p, int note, int vel, struct snd_midi_channel *chan)
    146{
    147	int ch;
    148	struct snd_emux *emu;
    149	struct snd_emux_voice *vp;
    150	unsigned long flags;
    151	struct snd_emux_port *port;
    152
    153	port = p;
    154	if (snd_BUG_ON(!port || !chan))
    155		return;
    156
    157	emu = port->emu;
    158	if (snd_BUG_ON(!emu || !emu->ops.release))
    159		return;
    160
    161	spin_lock_irqsave(&emu->voice_lock, flags);
    162	for (ch = 0; ch < emu->max_voices; ch++) {
    163		vp = &emu->voices[ch];
    164		if (STATE_IS_PLAYING(vp->state) &&
    165		    vp->chan == chan && vp->key == note) {
    166			vp->state = SNDRV_EMUX_ST_RELEASED;
    167			if (vp->ontime == jiffies) {
    168				/* if note-off is sent too shortly after
    169				 * note-on, emuX engine cannot produce the sound
    170				 * correctly.  so we'll release this note
    171				 * a bit later via timer callback.
    172				 */
    173				vp->state = SNDRV_EMUX_ST_PENDING;
    174				if (! emu->timer_active) {
    175					mod_timer(&emu->tlist, jiffies + 1);
    176					emu->timer_active = 1;
    177				}
    178			} else
    179				/* ok now release the note */
    180				emu->ops.release(vp);
    181		}
    182	}
    183	spin_unlock_irqrestore(&emu->voice_lock, flags);
    184}
    185
    186/*
    187 * timer callback
    188 *
    189 * release the pending note-offs
    190 */
    191void snd_emux_timer_callback(struct timer_list *t)
    192{
    193	struct snd_emux *emu = from_timer(emu, t, tlist);
    194	struct snd_emux_voice *vp;
    195	unsigned long flags;
    196	int ch, do_again = 0;
    197
    198	spin_lock_irqsave(&emu->voice_lock, flags);
    199	for (ch = 0; ch < emu->max_voices; ch++) {
    200		vp = &emu->voices[ch];
    201		if (vp->state == SNDRV_EMUX_ST_PENDING) {
    202			if (vp->ontime == jiffies)
    203				do_again++; /* release this at the next interrupt */
    204			else {
    205				emu->ops.release(vp);
    206				vp->state = SNDRV_EMUX_ST_RELEASED;
    207			}
    208		}
    209	}
    210	if (do_again) {
    211		mod_timer(&emu->tlist, jiffies + 1);
    212		emu->timer_active = 1;
    213	} else
    214		emu->timer_active = 0;
    215	spin_unlock_irqrestore(&emu->voice_lock, flags);
    216}
    217
    218/*
    219 * key pressure change
    220 */
    221void
    222snd_emux_key_press(void *p, int note, int vel, struct snd_midi_channel *chan)
    223{
    224	int ch;
    225	struct snd_emux *emu;
    226	struct snd_emux_voice *vp;
    227	unsigned long flags;
    228	struct snd_emux_port *port;
    229
    230	port = p;
    231	if (snd_BUG_ON(!port || !chan))
    232		return;
    233
    234	emu = port->emu;
    235	if (snd_BUG_ON(!emu || !emu->ops.update))
    236		return;
    237
    238	spin_lock_irqsave(&emu->voice_lock, flags);
    239	for (ch = 0; ch < emu->max_voices; ch++) {
    240		vp = &emu->voices[ch];
    241		if (vp->state == SNDRV_EMUX_ST_ON &&
    242		    vp->chan == chan && vp->key == note) {
    243			vp->velocity = vel;
    244			update_voice(emu, vp, SNDRV_EMUX_UPDATE_VOLUME);
    245		}
    246	}
    247	spin_unlock_irqrestore(&emu->voice_lock, flags);
    248}
    249
    250
    251/*
    252 * Modulate the voices which belong to the channel
    253 */
    254void
    255snd_emux_update_channel(struct snd_emux_port *port, struct snd_midi_channel *chan, int update)
    256{
    257	struct snd_emux *emu;
    258	struct snd_emux_voice *vp;
    259	int i;
    260	unsigned long flags;
    261
    262	if (! update)
    263		return;
    264
    265	emu = port->emu;
    266	if (snd_BUG_ON(!emu || !emu->ops.update))
    267		return;
    268
    269	spin_lock_irqsave(&emu->voice_lock, flags);
    270	for (i = 0; i < emu->max_voices; i++) {
    271		vp = &emu->voices[i];
    272		if (vp->chan == chan)
    273			update_voice(emu, vp, update);
    274	}
    275	spin_unlock_irqrestore(&emu->voice_lock, flags);
    276}
    277
    278/*
    279 * Modulate all the voices which belong to the port.
    280 */
    281void
    282snd_emux_update_port(struct snd_emux_port *port, int update)
    283{
    284	struct snd_emux *emu; 
    285	struct snd_emux_voice *vp;
    286	int i;
    287	unsigned long flags;
    288
    289	if (! update)
    290		return;
    291
    292	emu = port->emu;
    293	if (snd_BUG_ON(!emu || !emu->ops.update))
    294		return;
    295
    296	spin_lock_irqsave(&emu->voice_lock, flags);
    297	for (i = 0; i < emu->max_voices; i++) {
    298		vp = &emu->voices[i];
    299		if (vp->port == port)
    300			update_voice(emu, vp, update);
    301	}
    302	spin_unlock_irqrestore(&emu->voice_lock, flags);
    303}
    304
    305
    306/*
    307 * Deal with a controller type event.  This includes all types of
    308 * control events, not just the midi controllers
    309 */
    310void
    311snd_emux_control(void *p, int type, struct snd_midi_channel *chan)
    312{
    313	struct snd_emux_port *port;
    314
    315	port = p;
    316	if (snd_BUG_ON(!port || !chan))
    317		return;
    318
    319	switch (type) {
    320	case MIDI_CTL_MSB_MAIN_VOLUME:
    321	case MIDI_CTL_MSB_EXPRESSION:
    322		snd_emux_update_channel(port, chan, SNDRV_EMUX_UPDATE_VOLUME);
    323		break;
    324		
    325	case MIDI_CTL_MSB_PAN:
    326		snd_emux_update_channel(port, chan, SNDRV_EMUX_UPDATE_PAN);
    327		break;
    328
    329	case MIDI_CTL_SOFT_PEDAL:
    330#ifdef SNDRV_EMUX_USE_RAW_EFFECT
    331		/* FIXME: this is an emulation */
    332		if (chan->control[type] >= 64)
    333			snd_emux_send_effect(port, chan, EMUX_FX_CUTOFF, -160,
    334				     EMUX_FX_FLAG_ADD);
    335		else
    336			snd_emux_send_effect(port, chan, EMUX_FX_CUTOFF, 0,
    337				     EMUX_FX_FLAG_OFF);
    338#endif
    339		break;
    340
    341	case MIDI_CTL_PITCHBEND:
    342		snd_emux_update_channel(port, chan, SNDRV_EMUX_UPDATE_PITCH);
    343		break;
    344
    345	case MIDI_CTL_MSB_MODWHEEL:
    346	case MIDI_CTL_CHAN_PRESSURE:
    347		snd_emux_update_channel(port, chan,
    348					SNDRV_EMUX_UPDATE_FMMOD |
    349					SNDRV_EMUX_UPDATE_FM2FRQ2);
    350		break;
    351
    352	}
    353
    354	if (port->chset.midi_mode == SNDRV_MIDI_MODE_XG) {
    355		snd_emux_xg_control(port, chan, type);
    356	}
    357}
    358
    359
    360/*
    361 * terminate note - if free flag is true, free the terminated voice
    362 */
    363static void
    364terminate_note1(struct snd_emux *emu, int note, struct snd_midi_channel *chan, int free)
    365{
    366	int  i;
    367	struct snd_emux_voice *vp;
    368	unsigned long flags;
    369
    370	spin_lock_irqsave(&emu->voice_lock, flags);
    371	for (i = 0; i < emu->max_voices; i++) {
    372		vp = &emu->voices[i];
    373		if (STATE_IS_PLAYING(vp->state) && vp->chan == chan &&
    374		    vp->key == note)
    375			terminate_voice(emu, vp, free);
    376	}
    377	spin_unlock_irqrestore(&emu->voice_lock, flags);
    378}
    379
    380
    381/*
    382 * terminate note - exported for midi emulation
    383 */
    384void
    385snd_emux_terminate_note(void *p, int note, struct snd_midi_channel *chan)
    386{
    387	struct snd_emux *emu;
    388	struct snd_emux_port *port;
    389
    390	port = p;
    391	if (snd_BUG_ON(!port || !chan))
    392		return;
    393
    394	emu = port->emu;
    395	if (snd_BUG_ON(!emu || !emu->ops.terminate))
    396		return;
    397
    398	terminate_note1(emu, note, chan, 1);
    399}
    400
    401
    402/*
    403 * Terminate all the notes
    404 */
    405void
    406snd_emux_terminate_all(struct snd_emux *emu)
    407{
    408	int i;
    409	struct snd_emux_voice *vp;
    410	unsigned long flags;
    411
    412	spin_lock_irqsave(&emu->voice_lock, flags);
    413	for (i = 0; i < emu->max_voices; i++) {
    414		vp = &emu->voices[i];
    415		if (STATE_IS_PLAYING(vp->state))
    416			terminate_voice(emu, vp, 0);
    417		if (vp->state == SNDRV_EMUX_ST_OFF) {
    418			if (emu->ops.free_voice)
    419				emu->ops.free_voice(vp);
    420			if (emu->ops.reset)
    421				emu->ops.reset(emu, i);
    422		}
    423		vp->time = 0;
    424	}
    425	/* initialize allocation time */
    426	emu->use_time = 0;
    427	spin_unlock_irqrestore(&emu->voice_lock, flags);
    428}
    429
    430EXPORT_SYMBOL(snd_emux_terminate_all);
    431
    432/*
    433 * Terminate all voices associated with the given port
    434 */
    435void
    436snd_emux_sounds_off_all(struct snd_emux_port *port)
    437{
    438	int i;
    439	struct snd_emux *emu;
    440	struct snd_emux_voice *vp;
    441	unsigned long flags;
    442
    443	if (snd_BUG_ON(!port))
    444		return;
    445	emu = port->emu;
    446	if (snd_BUG_ON(!emu || !emu->ops.terminate))
    447		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(struct snd_emux *emu, struct snd_emux_port *port, int exclass)
    472{
    473	struct snd_emux_voice *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(struct snd_emux *emu, struct snd_emux_voice *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(struct snd_emux *emu, struct snd_emux_voice *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 const 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(struct snd_emux_voice *vp)
    547{
    548	struct soundfont_voice_parm *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 const 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(struct snd_emux_voice *vp)
    640{
    641	struct snd_midi_channel *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 const 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 const 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 const 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(struct snd_emux_voice *vp)
    741{
    742	int vol;
    743	int main_vol, expression_vol, master_vol;
    744	struct snd_midi_channel *chan = vp->chan;
    745	struct snd_emux_port *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		struct snd_emux_effect_table *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(struct snd_emux_voice *vp)
    812{
    813	struct snd_midi_channel *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		struct snd_emux_effect_table *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(struct snd_emux_port *port, struct snd_midi_channel *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(struct snd_emux *emu, struct snd_emux_port *port,
    890	 int *notep, int vel, struct snd_midi_channel *chan,
    891	 struct snd_sf_zone **table)
    892{
    893	int preset, bank, def_preset, def_bank;
    894
    895	bank = get_bank(port, chan);
    896	preset = chan->midi_program;
    897
    898	if (SF_IS_DRUM_BANK(bank)) {
    899		def_preset = port->ctrls[EMUX_MD_DEF_DRUM];
    900		def_bank = bank;
    901	} else {
    902		def_preset = preset;
    903		def_bank = port->ctrls[EMUX_MD_DEF_BANK];
    904	}
    905
    906	return snd_soundfont_search_zone(emu->sflist, notep, vel, preset, bank,
    907					 def_preset, def_bank,
    908					 table, SNDRV_EMUX_MAX_MULTI_VOICES);
    909}
    910
    911/*
    912 */
    913void
    914snd_emux_init_voices(struct snd_emux *emu)
    915{
    916	struct snd_emux_voice *vp;
    917	int i;
    918	unsigned long flags;
    919
    920	spin_lock_irqsave(&emu->voice_lock, flags);
    921	for (i = 0; i < emu->max_voices; i++) {
    922		vp = &emu->voices[i];
    923		vp->ch = -1; /* not used */
    924		vp->state = SNDRV_EMUX_ST_OFF;
    925		vp->chan = NULL;
    926		vp->port = NULL;
    927		vp->time = 0;
    928		vp->emu = emu;
    929		vp->hw = emu->hw;
    930	}
    931	spin_unlock_irqrestore(&emu->voice_lock, flags);
    932}
    933
    934/*
    935 */
    936void snd_emux_lock_voice(struct snd_emux *emu, int voice)
    937{
    938	unsigned long flags;
    939
    940	spin_lock_irqsave(&emu->voice_lock, flags);
    941	if (emu->voices[voice].state == SNDRV_EMUX_ST_OFF)
    942		emu->voices[voice].state = SNDRV_EMUX_ST_LOCKED;
    943	else
    944		snd_printk(KERN_WARNING
    945			   "invalid voice for lock %d (state = %x)\n",
    946			   voice, emu->voices[voice].state);
    947	spin_unlock_irqrestore(&emu->voice_lock, flags);
    948}
    949
    950EXPORT_SYMBOL(snd_emux_lock_voice);
    951
    952/*
    953 */
    954void snd_emux_unlock_voice(struct snd_emux *emu, int voice)
    955{
    956	unsigned long flags;
    957
    958	spin_lock_irqsave(&emu->voice_lock, flags);
    959	if (emu->voices[voice].state == SNDRV_EMUX_ST_LOCKED)
    960		emu->voices[voice].state = SNDRV_EMUX_ST_OFF;
    961	else
    962		snd_printk(KERN_WARNING
    963			   "invalid voice for unlock %d (state = %x)\n",
    964			   voice, emu->voices[voice].state);
    965	spin_unlock_irqrestore(&emu->voice_lock, flags);
    966}
    967
    968EXPORT_SYMBOL(snd_emux_unlock_voice);