/*
 *  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 <sound/asoundef.h>

/*
 * prototypes
 */
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 reset_voice(snd_emux_t *emu, int ch);
static void terminate_voice(snd_emux_voice_t *vp);
static void sysex(snd_emux_t *emu, char *buf, int len, int parsed, snd_midi_channel_set_t *chset);
#ifdef CONFIG_SND_SEQUENCER_OSS
static int oss_ioctl(snd_emux_t *emu, int cmd, int p1, int p2);
#endif
static int load_fx(snd_emux_t *emu, int type, int mode, const void __user *buf, long len);

static void set_pitch(emu8000_t *hw, snd_emux_voice_t *vp);
static void set_volume(emu8000_t *hw, snd_emux_voice_t *vp);
static void set_pan(emu8000_t *hw, snd_emux_voice_t *vp);
static void set_fmmod(emu8000_t *hw, snd_emux_voice_t *vp);
static void set_tremfreq(emu8000_t *hw, snd_emux_voice_t *vp);
static void set_fm2frq2(emu8000_t *hw, snd_emux_voice_t *vp);
static void set_filterQ(emu8000_t *hw, snd_emux_voice_t *vp);
static void snd_emu8000_tweak_voice(emu8000_t *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 snd_emux_operators_t 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(emu8000_t *hw)
{
	hw->emu->ops = emu8000_ops;
}



/*
 * Terminate a voice
 */
static void
release_voice(snd_emux_voice_t *vp)
{
	int dcysusv;
	emu8000_t *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(snd_emux_voice_t *vp)
{
	emu8000_t *hw; 

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


/*
 */
static void
update_voice(snd_emux_voice_t *vp, int update)
{
	emu8000_t *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 snd_emux_voice_t *
get_voice(snd_emux_t *emu, snd_emux_port_t *port)
{
	int  i;
	snd_emux_voice_t *vp;
	emu8000_t *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(snd_emux_voice_t *vp)
{
	unsigned int temp;
	int ch;
	int addr;
	snd_midi_channel_t *chan;
	emu8000_t *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(snd_emux_voice_t *vp)
{
	int ch = vp->ch;
	unsigned int temp;
	emu8000_t *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(snd_emux_t *emu, int ch)
{
	emu8000_t *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(emu8000_t *hw, snd_emux_voice_t *vp)
{
	EMU8000_IP_WRITE(hw, vp->ch, vp->apitch);
}

/*
 * Set the volume of a possibly already playing note
 */
static void
set_volume(emu8000_t *hw, snd_emux_voice_t *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(emu8000_t *hw, snd_emux_voice_t *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(emu8000_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;
	EMU8000_FMMOD_WRITE(hw, vp->ch, fmmod);
}

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

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

/* set filterQ */
static void
set_filterQ(emu8000_t *hw, snd_emux_voice_t *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(emu8000_t *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(snd_emux_t *emu, char *buf, int len, int parsed, snd_midi_channel_set_t *chset)
{
	emu8000_t *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(snd_emux_t *emu, int cmd, int p1, int p2)
{
	emu8000_t *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(snd_emux_t *emu, int type, int mode, const void __user *buf, long len)
{
	emu8000_t *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;
}

