/*
 *  synth callback routines for Emu10k1
 *
 *  Copyright (C) 2000 Takashi Iwai <tiwai@suse.de>
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 2 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program; if not, write to the Free Software
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 */

#include "emu10k1_synth_local.h"
#include <sound/asoundef.h>

/* voice status */
enum {
	V_FREE=0, V_OFF, V_RELEASED, V_PLAYING, V_END
};

/* Keeps track of what we are finding */
typedef struct best_voice {
	unsigned int time;
	int voice;
} best_voice_t;

/*
 * prototypes
 */
static void lookup_voices(snd_emux_t *emu, emu10k1_t *hw, best_voice_t *best, int active_only);
static snd_emux_voice_t *get_voice(snd_emux_t *emu, snd_emux_port_t *port);
static int start_voice(snd_emux_voice_t *vp);
static void trigger_voice(snd_emux_voice_t *vp);
static void release_voice(snd_emux_voice_t *vp);
static void update_voice(snd_emux_voice_t *vp, int update);
static void terminate_voice(snd_emux_voice_t *vp);
static void free_voice(snd_emux_voice_t *vp);

static void set_fmmod(emu10k1_t *hw, snd_emux_voice_t *vp);
static void set_fm2frq2(emu10k1_t *hw, snd_emux_voice_t *vp);
static void set_filterQ(emu10k1_t *hw, snd_emux_voice_t *vp);

/*
 * Ensure a value is between two points
 * macro evaluates its args more than once, so changed to upper-case.
 */
#define LIMITVALUE(x, a, b) do { if ((x) < (a)) (x) = (a); else if ((x) > (b)) (x) = (b); } while (0)
#define LIMITMAX(x, a) do {if ((x) > (a)) (x) = (a); } while (0)


/*
 * set up operators
 */
static snd_emux_operators_t emu10k1_ops = {
	.owner =	THIS_MODULE,
	.get_voice =	get_voice,
	.prepare =	start_voice,
	.trigger =	trigger_voice,
	.release =	release_voice,
	.update =	update_voice,
	.terminate =	terminate_voice,
	.free_voice =	free_voice,
	.sample_new =	snd_emu10k1_sample_new,
	.sample_free =	snd_emu10k1_sample_free,
};

void
snd_emu10k1_ops_setup(snd_emux_t *emu)
{
	emu->ops = emu10k1_ops;
}


/*
 * get more voice for pcm
 *
 * terminate most inactive voice and give it as a pcm voice.
 */
int
snd_emu10k1_synth_get_voice(emu10k1_t *hw)
{
	snd_emux_t *emu;
	snd_emux_voice_t *vp;
	best_voice_t best[V_END];
	unsigned long flags;
	int i;

	emu = hw->synth;

	spin_lock_irqsave(&emu->voice_lock, flags);
	lookup_voices(emu, hw, best, 1); /* no OFF voices */
	for (i = 0; i < V_END; i++) {
		if (best[i].voice >= 0) {
			int ch;
			vp = &emu->voices[best[i].voice];
			if ((ch = vp->ch) < 0) {
				//printk("synth_get_voice: ch < 0 (%d) ??", i);
				continue;
			}
			vp->emu->num_voices--;
			vp->ch = -1;
			vp->state = SNDRV_EMUX_ST_OFF;
			spin_unlock_irqrestore(&emu->voice_lock, flags);
			return ch;
		}
	}
	spin_unlock_irqrestore(&emu->voice_lock, flags);

	/* not found */
	return -ENOMEM;
}


/*
 * turn off the voice (not terminated)
 */
static void
release_voice(snd_emux_voice_t *vp)
{
	int dcysusv;
	emu10k1_t *hw;
	
	hw = vp->hw;
	dcysusv = 0x8000 | (unsigned char)vp->reg.parm.modrelease;
	snd_emu10k1_ptr_write(hw, DCYSUSM, vp->ch, dcysusv);
	dcysusv = 0x8000 | (unsigned char)vp->reg.parm.volrelease | DCYSUSV_CHANNELENABLE_MASK;
	snd_emu10k1_ptr_write(hw, DCYSUSV, vp->ch, dcysusv);
}


/*
 * terminate the voice
 */
static void
terminate_voice(snd_emux_voice_t *vp)
{
	emu10k1_t *hw;
	
	snd_assert(vp, return);
	hw = vp->hw;
	snd_emu10k1_ptr_write(hw, DCYSUSV, vp->ch, 0x807f | DCYSUSV_CHANNELENABLE_MASK);
	if (vp->block) {
		emu10k1_memblk_t *emem;
		emem = (emu10k1_memblk_t *)vp->block;
		if (emem->map_locked > 0)
			emem->map_locked--;
	}
}

/*
 * release the voice to system
 */
static void
free_voice(snd_emux_voice_t *vp)
{
	emu10k1_t *hw;
	
	hw = vp->hw;
	if (vp->ch >= 0) {
		snd_emu10k1_ptr_write(hw, IFATN, vp->ch, 0xff00);
		snd_emu10k1_ptr_write(hw, DCYSUSV, vp->ch, 0x807f | DCYSUSV_CHANNELENABLE_MASK);
		// snd_emu10k1_ptr_write(hw, DCYSUSV, vp->ch, 0);
		snd_emu10k1_ptr_write(hw, VTFT, vp->ch, 0xffff);
		snd_emu10k1_ptr_write(hw, CVCF, vp->ch, 0xffff);
		snd_emu10k1_voice_free(hw, &hw->voices[vp->ch]);
		vp->emu->num_voices--;
		vp->ch = -1;
	}
}


/*
 * update registers
 */
static void
update_voice(snd_emux_voice_t *vp, int update)
{
	emu10k1_t *hw;
	
	hw = vp->hw;
	if (update & SNDRV_EMUX_UPDATE_VOLUME)
		snd_emu10k1_ptr_write(hw, IFATN_ATTENUATION, vp->ch, vp->avol);
	if (update & SNDRV_EMUX_UPDATE_PITCH)
		snd_emu10k1_ptr_write(hw, IP, vp->ch, vp->apitch);
	if (update & SNDRV_EMUX_UPDATE_PAN) {
		snd_emu10k1_ptr_write(hw, PTRX_FXSENDAMOUNT_A, vp->ch, vp->apan);
		snd_emu10k1_ptr_write(hw, PTRX_FXSENDAMOUNT_B, vp->ch, vp->aaux);
	}
	if (update & SNDRV_EMUX_UPDATE_FMMOD)
		set_fmmod(hw, vp);
	if (update & SNDRV_EMUX_UPDATE_TREMFREQ)
		snd_emu10k1_ptr_write(hw, TREMFRQ, vp->ch, vp->reg.parm.tremfrq);
	if (update & SNDRV_EMUX_UPDATE_FM2FRQ2)
		set_fm2frq2(hw, vp);
	if (update & SNDRV_EMUX_UPDATE_Q)
		set_filterQ(hw, vp);
}


/*
 * look up voice table - get the best voice in order of preference
 */
/* spinlock held! */
static void
lookup_voices(snd_emux_t *emu, emu10k1_t *hw, best_voice_t *best, int active_only)
{
	snd_emux_voice_t *vp;
	best_voice_t *bp;
	int  i;

	for (i = 0; i < V_END; i++) {
		best[i].time = (unsigned int)-1; /* XXX MAX_?INT really */;
		best[i].voice = -1;
	}

	/*
	 * Go through them all and get a best one to use.
	 * NOTE: could also look at volume and pick the quietest one.
	 */
	for (i = 0; i < emu->max_voices; i++) {
		int state, val;

		vp = &emu->voices[i];
		state = vp->state;
		if (state == SNDRV_EMUX_ST_OFF) {
			if (vp->ch < 0) {
				if (active_only)
					continue;
				bp = best + V_FREE;
			} else
				bp = best + V_OFF;
		}
		else if (state == SNDRV_EMUX_ST_RELEASED ||
			 state == SNDRV_EMUX_ST_PENDING) {
			bp = best + V_RELEASED;
#if 0
			val = snd_emu10k1_ptr_read(hw, CVCF_CURRENTVOL, vp->ch);
			if (! val)
				bp = best + V_OFF;
#endif
		}
		else if (state == SNDRV_EMUX_ST_STANDBY)
			continue;
		else if (state & SNDRV_EMUX_ST_ON)
			bp = best + V_PLAYING;
		else
			continue;

		/* check if sample is finished playing (non-looping only) */
		if (bp != best + V_OFF && bp != best + V_FREE &&
		    (vp->reg.sample_mode & SNDRV_SFNT_SAMPLE_SINGLESHOT)) {
			val = snd_emu10k1_ptr_read(hw, CCCA_CURRADDR, vp->ch);
			if (val >= vp->reg.loopstart)
				bp = best + V_OFF;
		}

		if (vp->time < bp->time) {
			bp->time = vp->time;
			bp->voice = i;
		}
	}
}

/*
 * get an empty voice
 *
 * emu->voice_lock is already held.
 */
static snd_emux_voice_t *
get_voice(snd_emux_t *emu, snd_emux_port_t *port)
{
	emu10k1_t *hw;
	snd_emux_voice_t *vp;
	best_voice_t best[V_END];
	int i;

	hw = emu->hw;

	lookup_voices(emu, hw, best, 0);
	for (i = 0; i < V_END; i++) {
		if (best[i].voice >= 0) {
			vp = &emu->voices[best[i].voice];
			if (vp->ch < 0) {
				/* allocate a voice */
				emu10k1_voice_t *hwvoice;
				if (snd_emu10k1_voice_alloc(hw, EMU10K1_SYNTH, 1, &hwvoice) < 0 || hwvoice == NULL)
					continue;
				vp->ch = hwvoice->number;
				emu->num_voices++;
			}
			return vp;
		}
	}

	/* not found */
	return NULL;
}

/*
 * prepare envelopes and LFOs
 */
static int
start_voice(snd_emux_voice_t *vp)
{
	unsigned int temp;
	int ch;
	unsigned int addr, mapped_offset;
	snd_midi_channel_t *chan;
	emu10k1_t *hw;
	emu10k1_memblk_t *emem;
	
	hw = vp->hw;
	ch = vp->ch;
	snd_assert(ch >= 0, return -EINVAL);
	chan = vp->chan;

	emem = (emu10k1_memblk_t *)vp->block;
	if (emem == NULL)
		return -EINVAL;
	emem->map_locked++;
	if (snd_emu10k1_memblk_map(hw, emem) < 0) {
		// printk("emu: cannot map!\n");
		return -ENOMEM;
	}
	mapped_offset = snd_emu10k1_memblk_offset(emem) >> 1;
	vp->reg.start += mapped_offset;
	vp->reg.end += mapped_offset;
	vp->reg.loopstart += mapped_offset;
	vp->reg.loopend += mapped_offset;

	/* set channel routing */
	/* A = left(0), B = right(1), C = reverb(c), D = chorus(d) */
	if (hw->audigy) {
		temp = FXBUS_MIDI_LEFT | (FXBUS_MIDI_RIGHT << 8) | 
			(FXBUS_MIDI_REVERB << 16) | (FXBUS_MIDI_CHORUS << 24);
		snd_emu10k1_ptr_write(hw, A_FXRT1, ch, temp);
	} else {
		temp = (FXBUS_MIDI_LEFT << 16) | (FXBUS_MIDI_RIGHT << 20) | 
			(FXBUS_MIDI_REVERB << 24) | (FXBUS_MIDI_CHORUS << 28);
		snd_emu10k1_ptr_write(hw, FXRT, ch, temp);
	}

	/* channel to be silent and idle */
	snd_emu10k1_ptr_write(hw, DCYSUSV, ch, 0x0080);
	snd_emu10k1_ptr_write(hw, VTFT, ch, 0x0000FFFF);
	snd_emu10k1_ptr_write(hw, CVCF, ch, 0x0000FFFF);
	snd_emu10k1_ptr_write(hw, PTRX, ch, 0);
	snd_emu10k1_ptr_write(hw, CPF, ch, 0);

	/* set pitch offset */
	snd_emu10k1_ptr_write(hw, IP, vp->ch, vp->apitch);

	/* set envelope parameters */
	snd_emu10k1_ptr_write(hw, ENVVAL, ch, vp->reg.parm.moddelay);
	snd_emu10k1_ptr_write(hw, ATKHLDM, ch, vp->reg.parm.modatkhld);
	snd_emu10k1_ptr_write(hw, DCYSUSM, ch, vp->reg.parm.moddcysus);
	snd_emu10k1_ptr_write(hw, ENVVOL, ch, vp->reg.parm.voldelay);
	snd_emu10k1_ptr_write(hw, ATKHLDV, ch, vp->reg.parm.volatkhld);
	/* decay/sustain parameter for volume envelope is used
	   for triggerg the voice */

	/* cutoff and volume */
	temp = (unsigned int)vp->acutoff << 8 | (unsigned char)vp->avol;
	snd_emu10k1_ptr_write(hw, IFATN, vp->ch, temp);

	/* modulation envelope heights */
	snd_emu10k1_ptr_write(hw, PEFE, ch, vp->reg.parm.pefe);

	/* lfo1/2 delay */
	snd_emu10k1_ptr_write(hw, LFOVAL1, ch, vp->reg.parm.lfo1delay);
	snd_emu10k1_ptr_write(hw, LFOVAL2, ch, vp->reg.parm.lfo2delay);

	/* lfo1 pitch & cutoff shift */
	set_fmmod(hw, vp);
	/* lfo1 volume & freq */
	snd_emu10k1_ptr_write(hw, TREMFRQ, vp->ch, vp->reg.parm.tremfrq);
	/* lfo2 pitch & freq */
	set_fm2frq2(hw, vp);

	/* reverb and loop start (reverb 8bit, MSB) */
	temp = vp->reg.parm.reverb;
	temp += (int)vp->chan->control[MIDI_CTL_E1_REVERB_DEPTH] * 9 / 10;
	LIMITMAX(temp, 255);
	addr = vp->reg.loopstart;
	snd_emu10k1_ptr_write(hw, PSST, vp->ch, (temp << 24) | addr);

	/* chorus & loop end (chorus 8bit, MSB) */
	addr = vp->reg.loopend;
	temp = vp->reg.parm.chorus;
	temp += (int)chan->control[MIDI_CTL_E3_CHORUS_DEPTH] * 9 / 10;
	LIMITMAX(temp, 255);
	temp = (temp <<24) | addr;
	snd_emu10k1_ptr_write(hw, DSL, ch, temp);

	/* clear filter delay memory */
	snd_emu10k1_ptr_write(hw, Z1, ch, 0);
	snd_emu10k1_ptr_write(hw, Z2, ch, 0);

	/* invalidate maps */
	temp = (hw->silent_page.addr << 1) | MAP_PTI_MASK;
	snd_emu10k1_ptr_write(hw, MAPA, ch, temp);
	snd_emu10k1_ptr_write(hw, MAPB, ch, temp);
#if 0
	/* cache */
	{
		unsigned int val, sample;
		val = 32;
		if (vp->reg.sample_mode & SNDRV_SFNT_SAMPLE_8BITS)
			sample = 0x80808080;
		else {
			sample = 0;
			val *= 2;
		}

		/* cache */
		snd_emu10k1_ptr_write(hw, CCR, ch, 0x1c << 16);
		snd_emu10k1_ptr_write(hw, CDE, ch, sample);
		snd_emu10k1_ptr_write(hw, CDF, ch, sample);

		/* invalidate maps */
		temp = ((unsigned int)hw->silent_page.addr << 1) | MAP_PTI_MASK;
		snd_emu10k1_ptr_write(hw, MAPA, ch, temp);
		snd_emu10k1_ptr_write(hw, MAPB, ch, temp);
		
		/* fill cache */
		val -= 4;
		val <<= 25;
		val |= 0x1c << 16;
		snd_emu10k1_ptr_write(hw, CCR, ch, val);
	}
#endif

	/* Q & current address (Q 4bit value, MSB) */
	addr = vp->reg.start;
	temp = vp->reg.parm.filterQ;
	temp = (temp<<28) | addr;
	if (vp->apitch < 0xe400)
		temp |= CCCA_INTERPROM_0;
	else {
		unsigned int shift = (vp->apitch - 0xe000) >> 10;
		temp |= shift << 25;
	}
	if (vp->reg.sample_mode & SNDRV_SFNT_SAMPLE_8BITS)
		temp |= CCCA_8BITSELECT;
	snd_emu10k1_ptr_write(hw, CCCA, ch, temp);

	/* reset volume */
	temp = (unsigned int)vp->vtarget << 16;
	snd_emu10k1_ptr_write(hw, VTFT, ch, temp | vp->ftarget);
	snd_emu10k1_ptr_write(hw, CVCF, ch, temp | 0xff00);
	return 0;
}

/*
 * Start envelope
 */
static void
trigger_voice(snd_emux_voice_t *vp)
{
	unsigned int temp, ptarget;
	emu10k1_t *hw;
	emu10k1_memblk_t *emem;
	
	hw = vp->hw;

	emem = (emu10k1_memblk_t *)vp->block;
	if (! emem || emem->mapped_page < 0)
		return; /* not mapped */

#if 0
	ptarget = (unsigned int)vp->ptarget << 16;
#else
	ptarget = IP_TO_CP(vp->apitch);
#endif
	/* set pitch target and pan (volume) */
	temp = ptarget | (vp->apan << 8) | vp->aaux;
	snd_emu10k1_ptr_write(hw, PTRX, vp->ch, temp);

	/* pitch target */
	snd_emu10k1_ptr_write(hw, CPF, vp->ch, ptarget);

	/* trigger voice */
	snd_emu10k1_ptr_write(hw, DCYSUSV, vp->ch, vp->reg.parm.voldcysus|DCYSUSV_CHANNELENABLE_MASK);
}

#define MOD_SENSE 18

/* set lfo1 modulation height and cutoff */
static void
set_fmmod(emu10k1_t *hw, snd_emux_voice_t *vp)
{
	unsigned short fmmod;
	short pitch;
	unsigned char cutoff;
	int modulation;

	pitch = (char)(vp->reg.parm.fmmod>>8);
	cutoff = (vp->reg.parm.fmmod & 0xff);
	modulation = vp->chan->gm_modulation + vp->chan->midi_pressure;
	pitch += (MOD_SENSE * modulation) / 1200;
	LIMITVALUE(pitch, -128, 127);
	fmmod = ((unsigned char)pitch<<8) | cutoff;
	snd_emu10k1_ptr_write(hw, FMMOD, vp->ch, fmmod);
}

/* set lfo2 pitch & frequency */
static void
set_fm2frq2(emu10k1_t *hw, snd_emux_voice_t *vp)
{
	unsigned short fm2frq2;
	short pitch;
	unsigned char freq;
	int modulation;

	pitch = (char)(vp->reg.parm.fm2frq2>>8);
	freq = vp->reg.parm.fm2frq2 & 0xff;
	modulation = vp->chan->gm_modulation + vp->chan->midi_pressure;
	pitch += (MOD_SENSE * modulation) / 1200;
	LIMITVALUE(pitch, -128, 127);
	fm2frq2 = ((unsigned char)pitch<<8) | freq;
	snd_emu10k1_ptr_write(hw, FM2FRQ2, vp->ch, fm2frq2);
}

/* set filterQ */
static void
set_filterQ(emu10k1_t *hw, snd_emux_voice_t *vp)
{
	unsigned int val;
	val = snd_emu10k1_ptr_read(hw, CCCA, vp->ch) & ~CCCA_RESONANCE;
	val |= (vp->reg.parm.filterQ << 28);
	snd_emu10k1_ptr_write(hw, CCCA, vp->ch, val);
}
