/*
 *  synth callback routines for the emu8000 (AWE32/64)
 *
 *  Copyright (C) 1999 Steve Ratcliffe
 *  Copyright (C) 1999-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 "emu8000_local.h"
#include <linux/export.h>
#include <sound/asoundef.h>

/*
 * prototypes
 */
static struct snd_emux_voice *get_voice(struct snd_emux *emu,
					struct snd_emux_port *port);
static int start_voice(struct snd_emux_voice *vp);
static void trigger_voice(struct snd_emux_voice *vp);
static void release_voice(struct snd_emux_voice *vp);
static void update_voice(struct snd_emux_voice *vp, int update);
static void reset_voice(struct snd_emux *emu, int ch);
static void terminate_voice(struct snd_emux_voice *vp);
static void sysex(struct snd_emux *emu, char *buf, int len, int parsed,
		  struct snd_midi_channel_set *chset);
#ifdef CONFIG_SND_SEQUENCER_OSS
static int oss_ioctl(struct snd_emux *emu, int cmd, int p1, int p2);
#endif
static int load_fx(struct snd_emux *emu, int type, int mode,
		   const void __user *buf, long len);

static void set_pitch(struct snd_emu8000 *hw, struct snd_emux_voice *vp);
static void set_volume(struct snd_emu8000 *hw, struct snd_emux_voice *vp);
static void set_pan(struct snd_emu8000 *hw, struct snd_emux_voice *vp);
static void set_fmmod(struct snd_emu8000 *hw, struct snd_emux_voice *vp);
static void set_tremfreq(struct snd_emu8000 *hw, struct snd_emux_voice *vp);
static void set_fm2frq2(struct snd_emu8000 *hw, struct snd_emux_voice *vp);
static void set_filterQ(struct snd_emu8000 *hw, struct snd_emux_voice *vp);
static void snd_emu8000_tweak_voice(struct snd_emu8000 *emu, int ch);

/*
 * 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 struct snd_emux_operators emu8000_ops = {
	.owner =	THIS_MODULE,
	.get_voice =	get_voice,
	.prepare =	start_voice,
	.trigger =	trigger_voice,
	.release =	release_voice,
	.update =	update_voice,
	.terminate =	terminate_voice,
	.reset =	reset_voice,
	.sample_new =	snd_emu8000_sample_new,
	.sample_free =	snd_emu8000_sample_free,
	.sample_reset = snd_emu8000_sample_reset,
	.load_fx =	load_fx,
	.sysex =	sysex,
#ifdef CONFIG_SND_SEQUENCER_OSS
	.oss_ioctl =	oss_ioctl,
#endif
};

void
snd_emu8000_ops_setup(struct snd_emu8000 *hw)
{
	hw->emu->ops = emu8000_ops;
}



/*
 * Terminate a voice
 */
static void
release_voice(struct snd_emux_voice *vp)
{
	int dcysusv;
	struct snd_emu8000 *hw;

	hw = vp->hw;
	dcysusv = 0x8000 | (unsigned char)vp->reg.parm.modrelease;
	EMU8000_DCYSUS_WRITE(hw, vp->ch, dcysusv);
	dcysusv = 0x8000 | (unsigned char)vp->reg.parm.volrelease;
	EMU8000_DCYSUSV_WRITE(hw, vp->ch, dcysusv);
}


/*
 */
static void
terminate_voice(struct snd_emux_voice *vp)
{
	struct snd_emu8000 *hw; 

	hw = vp->hw;
	EMU8000_DCYSUSV_WRITE(hw, vp->ch, 0x807F);
}


/*
 */
static void
update_voice(struct snd_emux_voice *vp, int update)
{
	struct snd_emu8000 *hw;

	hw = vp->hw;
	if (update & SNDRV_EMUX_UPDATE_VOLUME)
		set_volume(hw, vp);
	if (update & SNDRV_EMUX_UPDATE_PITCH)
		set_pitch(hw, vp);
	if ((update & SNDRV_EMUX_UPDATE_PAN) &&
	    vp->port->ctrls[EMUX_MD_REALTIME_PAN])
		set_pan(hw, vp);
	if (update & SNDRV_EMUX_UPDATE_FMMOD)
		set_fmmod(hw, vp);
	if (update & SNDRV_EMUX_UPDATE_TREMFREQ)
		set_tremfreq(hw, vp);
	if (update & SNDRV_EMUX_UPDATE_FM2FRQ2)
		set_fm2frq2(hw, vp);
	if (update & SNDRV_EMUX_UPDATE_Q)
		set_filterQ(hw, vp);
}


/*
 * Find a channel (voice) within the EMU that is not in use or at least
 * less in use than other channels.  Always returns a valid pointer
 * no matter what.  If there is a real shortage of voices then one
 * will be cut. Such is life.
 *
 * The channel index (vp->ch) must be initialized in this routine.
 * In Emu8k, it is identical with the array index.
 */
static struct snd_emux_voice *
get_voice(struct snd_emux *emu, struct snd_emux_port *port)
{
	int  i;
	struct snd_emux_voice *vp;
	struct snd_emu8000 *hw;

	/* what we are looking for, in order of preference */
	enum {
		OFF=0, RELEASED, PLAYING, END
	};

	/* Keeps track of what we are finding */
	struct best {
		unsigned int  time;
		int voice;
	} best[END];
	struct best *bp;

	hw = emu->hw;

	for (i = 0; i < 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.
	 */
	for (i = 0; i < emu->max_voices; i++) {
		int state, val;

		vp = &emu->voices[i];
		state = vp->state;

		if (state == SNDRV_EMUX_ST_OFF)
			bp = best + OFF;
		else if (state == SNDRV_EMUX_ST_RELEASED ||
			 state == SNDRV_EMUX_ST_PENDING) {
			bp = best + RELEASED;
			val = (EMU8000_CVCF_READ(hw, vp->ch) >> 16) & 0xffff;
			if (! val)
				bp = best + OFF;
		}
		else if (state & SNDRV_EMUX_ST_ON)
			bp = best + PLAYING;
		else
			continue;

		/* check if sample is finished playing (non-looping only) */
		if (state != SNDRV_EMUX_ST_OFF &&
		    (vp->reg.sample_mode & SNDRV_SFNT_SAMPLE_SINGLESHOT)) {
			val = EMU8000_CCCA_READ(hw, vp->ch) & 0xffffff;
			if (val >= vp->reg.loopstart)
				bp = best + OFF;
		}

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

	for (i = 0; i < END; i++) {
		if (best[i].voice >= 0) {
			vp = &emu->voices[best[i].voice];
			vp->ch = best[i].voice;
			return vp;
		}
	}

	/* not found */
	return NULL;
}

/*
 */
static int
start_voice(struct snd_emux_voice *vp)
{
	unsigned int temp;
	int ch;
	int addr;
	struct snd_midi_channel *chan;
	struct snd_emu8000 *hw;

	hw = vp->hw;
	ch = vp->ch;
	chan = vp->chan;

	/* channel to be silent and idle */
	EMU8000_DCYSUSV_WRITE(hw, ch, 0x0080);
	EMU8000_VTFT_WRITE(hw, ch, 0x0000FFFF);
	EMU8000_CVCF_WRITE(hw, ch, 0x0000FFFF);
	EMU8000_PTRX_WRITE(hw, ch, 0);
	EMU8000_CPF_WRITE(hw, ch, 0);

	/* set pitch offset */
	set_pitch(hw, vp);

	/* set envelope parameters */
	EMU8000_ENVVAL_WRITE(hw, ch, vp->reg.parm.moddelay);
	EMU8000_ATKHLD_WRITE(hw, ch, vp->reg.parm.modatkhld);
	EMU8000_DCYSUS_WRITE(hw, ch, vp->reg.parm.moddcysus);
	EMU8000_ENVVOL_WRITE(hw, ch, vp->reg.parm.voldelay);
	EMU8000_ATKHLDV_WRITE(hw, ch, vp->reg.parm.volatkhld);
	/* decay/sustain parameter for volume envelope is used
	   for triggerg the voice */

	/* cutoff and volume */
	set_volume(hw, vp);

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

	/* lfo1/2 delay */
	EMU8000_LFO1VAL_WRITE(hw, ch, vp->reg.parm.lfo1delay);
	EMU8000_LFO2VAL_WRITE(hw, ch, vp->reg.parm.lfo2delay);

	/* lfo1 pitch & cutoff shift */
	set_fmmod(hw, vp);
	/* lfo1 volume & freq */
	set_tremfreq(hw, vp);
	/* lfo2 pitch & freq */
	set_fm2frq2(hw, vp);
	/* pan & loop start */
	set_pan(hw, vp);

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

	/* Q & current address (Q 4bit value, MSB) */
	addr = vp->reg.start - 1;
	temp = vp->reg.parm.filterQ;
	temp = (temp<<28) | (unsigned int)addr;
	EMU8000_CCCA_WRITE(hw, ch, temp);

	/* clear unknown registers */
	EMU8000_00A0_WRITE(hw, ch, 0);
	EMU8000_0080_WRITE(hw, ch, 0);

	/* reset volume */
	temp = vp->vtarget << 16;
	EMU8000_VTFT_WRITE(hw, ch, temp | vp->ftarget);
	EMU8000_CVCF_WRITE(hw, ch, temp | 0xff00);

	return 0;
}

/*
 * Start envelope
 */
static void
trigger_voice(struct snd_emux_voice *vp)
{
	int ch = vp->ch;
	unsigned int temp;
	struct snd_emu8000 *hw;

	hw = vp->hw;

	/* set reverb and pitch target */
	temp = vp->reg.parm.reverb;
	temp += (int)vp->chan->control[MIDI_CTL_E1_REVERB_DEPTH] * 9 / 10;
	LIMITMAX(temp, 255);
	temp = (temp << 8) | (vp->ptarget << 16) | vp->aaux;
	EMU8000_PTRX_WRITE(hw, ch, temp);
	EMU8000_CPF_WRITE(hw, ch, vp->ptarget << 16);
	EMU8000_DCYSUSV_WRITE(hw, ch, vp->reg.parm.voldcysus);
}

/*
 * reset voice parameters
 */
static void
reset_voice(struct snd_emux *emu, int ch)
{
	struct snd_emu8000 *hw;

	hw = emu->hw;
	EMU8000_DCYSUSV_WRITE(hw, ch, 0x807F);
	snd_emu8000_tweak_voice(hw, ch);
}

/*
 * Set the pitch of a possibly playing note.
 */
static void
set_pitch(struct snd_emu8000 *hw, struct snd_emux_voice *vp)
{
	EMU8000_IP_WRITE(hw, vp->ch, vp->apitch);
}

/*
 * Set the volume of a possibly already playing note
 */
static void
set_volume(struct snd_emu8000 *hw, struct snd_emux_voice *vp)
{
	int  ifatn;

	ifatn = (unsigned char)vp->acutoff;
	ifatn = (ifatn << 8);
	ifatn |= (unsigned char)vp->avol;
	EMU8000_IFATN_WRITE(hw, vp->ch, ifatn);
}

/*
 * Set pan and loop start address.
 */
static void
set_pan(struct snd_emu8000 *hw, struct snd_emux_voice *vp)
{
	unsigned int temp;

	temp = ((unsigned int)vp->apan<<24) | ((unsigned int)vp->reg.loopstart - 1);
	EMU8000_PSST_WRITE(hw, vp->ch, temp);
}

#define MOD_SENSE 18

static void
set_fmmod(struct snd_emu8000 *hw, struct snd_emux_voice *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;
	EMU8000_FMMOD_WRITE(hw, vp->ch, fmmod);
}

/* set tremolo (lfo1) volume & frequency */
static void
set_tremfreq(struct snd_emu8000 *hw, struct snd_emux_voice *vp)
{
	EMU8000_TREMFRQ_WRITE(hw, vp->ch, vp->reg.parm.tremfrq);
}

/* set lfo2 pitch & frequency */
static void
set_fm2frq2(struct snd_emu8000 *hw, struct snd_emux_voice *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;
	EMU8000_FM2FRQ2_WRITE(hw, vp->ch, fm2frq2);
}

/* set filterQ */
static void
set_filterQ(struct snd_emu8000 *hw, struct snd_emux_voice *vp)
{
	unsigned int addr;
	addr = EMU8000_CCCA_READ(hw, vp->ch) & 0xffffff;
	addr |= (vp->reg.parm.filterQ << 28);
	EMU8000_CCCA_WRITE(hw, vp->ch, addr);
}

/*
 * set the envelope & LFO parameters to the default values
 */
static void
snd_emu8000_tweak_voice(struct snd_emu8000 *emu, int i)
{
	/* set all mod/vol envelope shape to minimum */
	EMU8000_ENVVOL_WRITE(emu, i, 0x8000);
	EMU8000_ENVVAL_WRITE(emu, i, 0x8000);
	EMU8000_DCYSUS_WRITE(emu, i, 0x7F7F);
	EMU8000_ATKHLDV_WRITE(emu, i, 0x7F7F);
	EMU8000_ATKHLD_WRITE(emu, i, 0x7F7F);
	EMU8000_PEFE_WRITE(emu, i, 0);  /* mod envelope height to zero */
	EMU8000_LFO1VAL_WRITE(emu, i, 0x8000); /* no delay for LFO1 */
	EMU8000_LFO2VAL_WRITE(emu, i, 0x8000);
	EMU8000_IP_WRITE(emu, i, 0xE000);	/* no pitch shift */
	EMU8000_IFATN_WRITE(emu, i, 0xFF00);	/* volume to minimum */
	EMU8000_FMMOD_WRITE(emu, i, 0);
	EMU8000_TREMFRQ_WRITE(emu, i, 0);
	EMU8000_FM2FRQ2_WRITE(emu, i, 0);
}

/*
 * sysex callback
 */
static void
sysex(struct snd_emux *emu, char *buf, int len, int parsed, struct snd_midi_channel_set *chset)
{
	struct snd_emu8000 *hw;

	hw = emu->hw;

	switch (parsed) {
	case SNDRV_MIDI_SYSEX_GS_CHORUS_MODE:
		hw->chorus_mode = chset->gs_chorus_mode;
		snd_emu8000_update_chorus_mode(hw);
		break;

	case SNDRV_MIDI_SYSEX_GS_REVERB_MODE:
		hw->reverb_mode = chset->gs_reverb_mode;
		snd_emu8000_update_reverb_mode(hw);
		break;
	}
}


#ifdef CONFIG_SND_SEQUENCER_OSS
/*
 * OSS ioctl callback
 */
static int
oss_ioctl(struct snd_emux *emu, int cmd, int p1, int p2)
{
	struct snd_emu8000 *hw;

	hw = emu->hw;

	switch (cmd) {
	case _EMUX_OSS_REVERB_MODE:
		hw->reverb_mode = p1;
		snd_emu8000_update_reverb_mode(hw);
		break;

	case _EMUX_OSS_CHORUS_MODE:
		hw->chorus_mode = p1;
		snd_emu8000_update_chorus_mode(hw);
		break;

	case _EMUX_OSS_INITIALIZE_CHIP:
		/* snd_emu8000_init(hw); */ /*ignored*/
		break;

	case _EMUX_OSS_EQUALIZER:
		hw->bass_level = p1;
		hw->treble_level = p2;
		snd_emu8000_update_equalizer(hw);
		break;
	}
	return 0;
}
#endif


/*
 * additional patch keys
 */

#define SNDRV_EMU8000_LOAD_CHORUS_FX	0x10	/* optarg=mode */
#define SNDRV_EMU8000_LOAD_REVERB_FX	0x11	/* optarg=mode */


/*
 * callback routine
 */

static int
load_fx(struct snd_emux *emu, int type, int mode, const void __user *buf, long len)
{
	struct snd_emu8000 *hw;
	hw = emu->hw;

	/* skip header */
	buf += 16;
	len -= 16;

	switch (type) {
	case SNDRV_EMU8000_LOAD_CHORUS_FX:
		return snd_emu8000_load_chorus_fx(hw, mode, buf, len);
	case SNDRV_EMU8000_LOAD_REVERB_FX:
		return snd_emu8000_load_reverb_fx(hw, mode, buf, len);
	}
	return -EINVAL;
}

