/*
 *  Soundfont generic routines.
 *	It is intended that these should be used by any driver that is willing
 *	to accept soundfont patches.
 *
 *  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
 */
/*
 * Deal with reading in of a soundfont.  Code follows the OSS way
 * of doing things so that the old sfxload utility can be used.
 * Everything may change when there is an alsa way of doing things.
 */
#include <sound/driver.h>
#include <asm/uaccess.h>
#include <linux/slab.h>
#include <sound/core.h>
#include <sound/soundfont.h>
#include <sound/seq_oss_legacy.h>

/* Prototypes for static functions */

static int open_patch(snd_sf_list_t *sflist, const char __user *data, int count, int client);
static snd_soundfont_t *newsf(snd_sf_list_t *sflist, int type, char *name);
static int is_identical_font(snd_soundfont_t *sf, int type, unsigned char *name);
static int close_patch(snd_sf_list_t *sflist);
static int probe_data(snd_sf_list_t *sflist, int sample_id);
static void set_zone_counter(snd_sf_list_t *sflist, snd_soundfont_t *sf, snd_sf_zone_t *zp);
static snd_sf_zone_t *sf_zone_new(snd_sf_list_t *sflist, snd_soundfont_t *sf);
static void set_sample_counter(snd_sf_list_t *sflist, snd_soundfont_t *sf, snd_sf_sample_t *sp);
static snd_sf_sample_t *sf_sample_new(snd_sf_list_t *sflist, snd_soundfont_t *sf);
static void sf_sample_delete(snd_sf_list_t *sflist, snd_soundfont_t *sf, snd_sf_sample_t *sp);
static int load_map(snd_sf_list_t *sflist, const void __user *data, int count);
static int load_info(snd_sf_list_t *sflist, const void __user *data, long count);
static int remove_info(snd_sf_list_t *sflist, snd_soundfont_t *sf, int bank, int instr);
static void init_voice_info(soundfont_voice_info_t *avp);
static void init_voice_parm(soundfont_voice_parm_t *pp);
static snd_sf_sample_t *set_sample(snd_soundfont_t *sf, soundfont_voice_info_t *avp);
static snd_sf_sample_t *find_sample(snd_soundfont_t *sf, int sample_id);
static int load_data(snd_sf_list_t *sflist, const void __user *data, long count);
static void rebuild_presets(snd_sf_list_t *sflist);
static void add_preset(snd_sf_list_t *sflist, snd_sf_zone_t *cur);
static void delete_preset(snd_sf_list_t *sflist, snd_sf_zone_t *zp);
static snd_sf_zone_t *search_first_zone(snd_sf_list_t *sflist, int bank, int preset, int key);
static int search_zones(snd_sf_list_t *sflist, int *notep, int vel, int preset, int bank, snd_sf_zone_t **table, int max_layers, int level);
static int get_index(int bank, int instr, int key);
static void snd_sf_init(snd_sf_list_t *sflist);
static void snd_sf_clear(snd_sf_list_t *sflist);

/*
 * lock access to sflist
 */
static void
lock_preset(snd_sf_list_t *sflist)
{
	unsigned long flags;
	down(&sflist->presets_mutex);
	spin_lock_irqsave(&sflist->lock, flags);
	sflist->presets_locked = 1;
	spin_unlock_irqrestore(&sflist->lock, flags);
}


/*
 * remove lock
 */
static void
unlock_preset(snd_sf_list_t *sflist)
{
	unsigned long flags;
	spin_lock_irqsave(&sflist->lock, flags);
	sflist->presets_locked = 0;
	spin_unlock_irqrestore(&sflist->lock, flags);
	up(&sflist->presets_mutex);
}


/*
 * close the patch if the patch was opened by this client.
 */
int
snd_soundfont_close_check(snd_sf_list_t *sflist, int client)
{
	unsigned long flags;
	spin_lock_irqsave(&sflist->lock, flags);
	if (sflist->open_client == client)  {
		spin_unlock_irqrestore(&sflist->lock, flags);
		return close_patch(sflist);
	}
	spin_unlock_irqrestore(&sflist->lock, flags);
	return 0;
}


/*
 * Deal with a soundfont patch.  Any driver could use these routines
 * although it was designed for the AWE64.
 *
 * The sample_write and callargs pararameters allow a callback into
 * the actual driver to write sample data to the board or whatever
 * it wants to do with it.
 */
int
snd_soundfont_load(snd_sf_list_t *sflist, const void __user *data, long count, int client)
{
	soundfont_patch_info_t patch;
	unsigned long flags;
	int  rc;

	if (count < (long)sizeof(patch)) {
		snd_printk("patch record too small %ld\n", count);
		return -EINVAL;
	}
	if (copy_from_user(&patch, data, sizeof(patch)))
		return -EFAULT;

	count -= sizeof(patch);
	data += sizeof(patch);

	if (patch.key != SNDRV_OSS_SOUNDFONT_PATCH) {
		snd_printk("'The wrong kind of patch' %x\n", patch.key);
		return -EINVAL;
	}
	if (count < patch.len) {
		snd_printk("Patch too short %ld, need %d\n", count, patch.len);
		return -EINVAL;
	}
	if (patch.len < 0) {
		snd_printk("poor length %d\n", patch.len);
		return -EINVAL;
	}

	if (patch.type == SNDRV_SFNT_OPEN_PATCH) {
		/* grab sflist to open */
		lock_preset(sflist);
		rc = open_patch(sflist, data, count, client);
		unlock_preset(sflist);
		return rc;
	}

	/* check if other client already opened patch */
	spin_lock_irqsave(&sflist->lock, flags);
	if (sflist->open_client != client) {
		spin_unlock_irqrestore(&sflist->lock, flags);
		return -EBUSY;
	}
	spin_unlock_irqrestore(&sflist->lock, flags);

	lock_preset(sflist);
	rc = -EINVAL;
	switch (patch.type) {
	case SNDRV_SFNT_LOAD_INFO:
		rc = load_info(sflist, data, count);
		break;
	case SNDRV_SFNT_LOAD_DATA:
		rc = load_data(sflist, data, count);
		break;
	case SNDRV_SFNT_CLOSE_PATCH:
		rc = close_patch(sflist);
		break;
	case SNDRV_SFNT_REPLACE_DATA:
		/*rc = replace_data(&patch, data, count);*/
		break;
	case SNDRV_SFNT_MAP_PRESET:
		rc = load_map(sflist, data, count);
		break;
	case SNDRV_SFNT_PROBE_DATA:
		rc = probe_data(sflist, patch.optarg);
		break;
	case SNDRV_SFNT_REMOVE_INFO:
		/* patch must be opened */
		if (sflist->currsf) {
			snd_printk("soundfont: remove_info: patch not opened\n");
			rc = -EINVAL;
		} else {
			int bank, instr;
			bank = ((unsigned short)patch.optarg >> 8) & 0xff;
			instr = (unsigned short)patch.optarg & 0xff;
			if (! remove_info(sflist, sflist->currsf, bank, instr))
				rc = -EINVAL;
			else
				rc = 0;
		}
		break;
	}
	unlock_preset(sflist);

	return rc;
}


/* check if specified type is special font (GUS or preset-alias) */
static inline int
is_special_type(int type)
{
	type &= 0x0f;
	return (type == SNDRV_SFNT_PAT_TYPE_GUS ||
		type == SNDRV_SFNT_PAT_TYPE_MAP);
}


/* open patch; create sf list */
static int
open_patch(snd_sf_list_t *sflist, const char __user *data, int count, int client)
{
	soundfont_open_parm_t parm;
	snd_soundfont_t *sf;
	unsigned long flags;

	spin_lock_irqsave(&sflist->lock, flags);
	if (sflist->open_client >= 0 || sflist->currsf) {
		spin_unlock_irqrestore(&sflist->lock, flags);
		return -EBUSY;
	}
	spin_unlock_irqrestore(&sflist->lock, flags);

	if (copy_from_user(&parm, data, sizeof(parm)))
		return -EFAULT;

	if (is_special_type(parm.type)) {
		parm.type |= SNDRV_SFNT_PAT_SHARED;
		sf = newsf(sflist, parm.type, NULL);
	} else 
		sf = newsf(sflist, parm.type, parm.name);
	if (sf == NULL) {
		return -ENOMEM;
	}

	spin_lock_irqsave(&sflist->lock, flags);
	sflist->open_client = client;
	sflist->currsf = sf;
	spin_unlock_irqrestore(&sflist->lock, flags);

	return 0;
}

/*
 * Allocate a new soundfont structure.
 */
static snd_soundfont_t *
newsf(snd_sf_list_t *sflist, int type, char *name)
{
	snd_soundfont_t *sf;

	/* check the shared fonts */
	if (type & SNDRV_SFNT_PAT_SHARED) {
		for (sf = sflist->fonts; sf; sf = sf->next) {
			if (is_identical_font(sf, type, name)) {
				return sf;
			}
		}
	}

	/* not found -- create a new one */
	sf = kcalloc(1, sizeof(*sf), GFP_KERNEL);
	if (sf == NULL)
		return NULL;
	sf->id = sflist->fonts_size;
	sflist->fonts_size++;

	/* prepend this record */
	sf->next = sflist->fonts;
	sflist->fonts = sf;

	sf->type = type;
	sf->zones = NULL;
	sf->samples = NULL;
	if (name)
		memcpy(sf->name, name, SNDRV_SFNT_PATCH_NAME_LEN);

	return sf;
}

/* check if the given name matches to the existing list */
static int
is_identical_font(snd_soundfont_t *sf, int type, unsigned char *name)
{
	return ((sf->type & SNDRV_SFNT_PAT_SHARED) &&
		(sf->type & 0x0f) == (type & 0x0f) &&
		(name == NULL ||
		 memcmp(sf->name, name, SNDRV_SFNT_PATCH_NAME_LEN) == 0));
}

/*
 * Close the current patch.
 */
static int
close_patch(snd_sf_list_t *sflist)
{
	unsigned long flags;

	spin_lock_irqsave(&sflist->lock, flags);
	sflist->currsf = NULL;
	sflist->open_client = -1;
	spin_unlock_irqrestore(&sflist->lock, flags);

	rebuild_presets(sflist);

	return 0;

}

/* probe sample in the current list -- nothing to be loaded */
static int
probe_data(snd_sf_list_t *sflist, int sample_id)
{
	/* patch must be opened */
	if (sflist->currsf) {
		/* search the specified sample by optarg */
		if (find_sample(sflist->currsf, sample_id))
			return 0;
	}
	return -EINVAL;
}

/*
 * increment zone counter
 */
static void
set_zone_counter(snd_sf_list_t *sflist, snd_soundfont_t *sf, snd_sf_zone_t *zp)
{
	zp->counter = sflist->zone_counter++;
	if (sf->type & SNDRV_SFNT_PAT_LOCKED)
		sflist->zone_locked = sflist->zone_counter;
}

/*
 * allocate a new zone record
 */
static snd_sf_zone_t *
sf_zone_new(snd_sf_list_t *sflist, snd_soundfont_t *sf)
{
	snd_sf_zone_t *zp;

	if ((zp = kcalloc(1, sizeof(*zp), GFP_KERNEL)) == NULL)
		return NULL;
	zp->next = sf->zones;
	sf->zones = zp;

	init_voice_info(&zp->v);

	set_zone_counter(sflist, sf, zp);
	return zp;
}


/*
 * increment sample couter
 */
static void
set_sample_counter(snd_sf_list_t *sflist, snd_soundfont_t *sf, snd_sf_sample_t *sp)
{
	sp->counter = sflist->sample_counter++;
	if (sf->type & SNDRV_SFNT_PAT_LOCKED)
		sflist->sample_locked = sflist->sample_counter;
}

/*
 * allocate a new sample list record
 */
static snd_sf_sample_t *
sf_sample_new(snd_sf_list_t *sflist, snd_soundfont_t *sf)
{
	snd_sf_sample_t *sp;

	if ((sp = kcalloc(1, sizeof(*sp), GFP_KERNEL)) == NULL)
		return NULL;

	sp->next = sf->samples;
	sf->samples = sp;

	set_sample_counter(sflist, sf, sp);
	return sp;
}

/*
 * delete sample list -- this is an exceptional job.
 * only the last allocated sample can be deleted.
 */
static void
sf_sample_delete(snd_sf_list_t *sflist, snd_soundfont_t *sf, snd_sf_sample_t *sp)
{
	/* only last sample is accepted */
	if (sp == sf->samples) {
		sf->samples = sp->next;
		kfree(sp);
	}
}


/* load voice map */
static int
load_map(snd_sf_list_t *sflist, const void __user *data, int count)
{
	snd_sf_zone_t *zp, *prevp;
	snd_soundfont_t *sf;
	soundfont_voice_map_t map;

	/* get the link info */
	if (count < (int)sizeof(map))
		return -EINVAL;
	if (copy_from_user(&map, data, sizeof(map)))
		return -EFAULT;

	if (map.map_instr < 0 || map.map_instr >= SF_MAX_INSTRUMENTS)
		return -EINVAL;
	
	sf = newsf(sflist, SNDRV_SFNT_PAT_TYPE_MAP|SNDRV_SFNT_PAT_SHARED, NULL);
	if (sf == NULL)
		return -ENOMEM;

	prevp = NULL;
	for (zp = sf->zones; zp; prevp = zp, zp = zp->next) {
		if (zp->mapped &&
		    zp->instr == map.map_instr &&
		    zp->bank == map.map_bank &&
		    zp->v.low == map.map_key &&
		    zp->v.start == map.src_instr &&
		    zp->v.end == map.src_bank &&
		    zp->v.fixkey == map.src_key) {
			/* the same mapping is already present */
			/* relink this record to the link head */
			if (prevp) {
				prevp->next = zp->next;
				zp->next = sf->zones;
				sf->zones = zp;
			}
			/* update the counter */
			set_zone_counter(sflist, sf, zp);
			return 0;
		}
	}

	/* create a new zone */
	if ((zp = sf_zone_new(sflist, sf)) == NULL)
		return -ENOMEM;

	zp->bank = map.map_bank;
	zp->instr = map.map_instr;
	zp->mapped = 1;
	if (map.map_key >= 0) {
		zp->v.low = map.map_key;
		zp->v.high = map.map_key;
	}
	zp->v.start = map.src_instr;
	zp->v.end = map.src_bank;
	zp->v.fixkey = map.src_key;
	zp->v.sf_id = sf->id;

	add_preset(sflist, zp);

	return 0;
}


/* remove the present instrument layers */
static int
remove_info(snd_sf_list_t *sflist, snd_soundfont_t *sf, int bank, int instr)
{
	snd_sf_zone_t *prev, *next, *p;
	int removed = 0;

	prev = NULL;
	for (p = sf->zones; p; p = next) {
		next = p->next;
		if (! p->mapped &&
		    p->bank == bank && p->instr == instr) {
			/* remove this layer */
			if (prev)
				prev->next = next;
			else
				sf->zones = next;
			removed++;
			kfree(p);
		} else
			prev = p;
	}
	if (removed)
		rebuild_presets(sflist);
	return removed;
}


/*
 * Read an info record from the user buffer and save it on the current
 * open soundfont.
 */
static int
load_info(snd_sf_list_t *sflist, const void __user *data, long count)
{
	snd_soundfont_t *sf;
	snd_sf_zone_t *zone;
	soundfont_voice_rec_hdr_t hdr;
	int i;

	/* patch must be opened */
	if ((sf = sflist->currsf) == NULL)
		return -EINVAL;

	if (is_special_type(sf->type))
		return -EINVAL;

	if (count < (long)sizeof(hdr)) {
		printk("Soundfont error: invalid patch zone length\n");
		return -EINVAL;
	}
	if (copy_from_user((char*)&hdr, data, sizeof(hdr)))
		return -EFAULT;
	
	data += sizeof(hdr);
	count -= sizeof(hdr);

	if (hdr.nvoices <= 0 || hdr.nvoices >= 100) {
		printk("Soundfont error: Illegal voice number %d\n", hdr.nvoices);
		return -EINVAL;
	}

	if (count < (long)sizeof(soundfont_voice_info_t)*hdr.nvoices) {
		printk("Soundfont Error: patch length(%ld) is smaller than nvoices(%d)\n",
		       count, hdr.nvoices);
		return -EINVAL;
	}

	switch (hdr.write_mode) {
	case SNDRV_SFNT_WR_EXCLUSIVE:
		/* exclusive mode - if the instrument already exists,
		   return error */
		for (zone = sf->zones; zone; zone = zone->next) {
			if (!zone->mapped &&
			    zone->bank == hdr.bank &&
			    zone->instr == hdr.instr)
				return -EINVAL;
		}
		break;
	case SNDRV_SFNT_WR_REPLACE:
		/* replace mode - remove the instrument if it already exists */
		remove_info(sflist, sf, hdr.bank, hdr.instr);
		break;
	}

	for (i = 0; i < hdr.nvoices; i++) {
		snd_sf_zone_t tmpzone;

		/* copy awe_voice_info parameters */
		if (copy_from_user(&tmpzone.v, data, sizeof(tmpzone.v))) {
			return -EFAULT;
		}

		data += sizeof(tmpzone.v);
		count -= sizeof(tmpzone.v);

		tmpzone.bank = hdr.bank;
		tmpzone.instr = hdr.instr;
		tmpzone.mapped = 0;
		tmpzone.v.sf_id = sf->id;
		if (tmpzone.v.mode & SNDRV_SFNT_MODE_INIT_PARM)
			init_voice_parm(&tmpzone.v.parm);

		/* create a new zone */
		if ((zone = sf_zone_new(sflist, sf)) == NULL) {
			return -ENOMEM;
		}

		/* copy the temporary data */
		zone->bank = tmpzone.bank;
		zone->instr = tmpzone.instr;
		zone->v = tmpzone.v;

		/* look up the sample */
		zone->sample = set_sample(sf, &zone->v);
	}

	return 0;
}


/* initialize voice_info record */
static void
init_voice_info(soundfont_voice_info_t *avp)
{
	memset(avp, 0, sizeof(*avp));

	avp->root = 60;
	avp->high = 127;
	avp->velhigh = 127;
	avp->fixkey = -1;
	avp->fixvel = -1;
	avp->fixpan = -1;
	avp->pan = -1;
	avp->amplitude = 127;
	avp->scaleTuning = 100;

	init_voice_parm(&avp->parm);
}

/* initialize voice_parm record:
 * Env1/2: delay=0, attack=0, hold=0, sustain=0, decay=0, release=0.
 * Vibrato and Tremolo effects are zero.
 * Cutoff is maximum.
 * Chorus and Reverb effects are zero.
 */
static void
init_voice_parm(soundfont_voice_parm_t *pp)
{
	memset(pp, 0, sizeof(*pp));

	pp->moddelay = 0x8000;
	pp->modatkhld = 0x7f7f;
	pp->moddcysus = 0x7f7f;
	pp->modrelease = 0x807f;

	pp->voldelay = 0x8000;
	pp->volatkhld = 0x7f7f;
	pp->voldcysus = 0x7f7f;
	pp->volrelease = 0x807f;

	pp->lfo1delay = 0x8000;
	pp->lfo2delay = 0x8000;

	pp->cutoff = 0xff;
}	

/* search the specified sample */
static snd_sf_sample_t *
set_sample(snd_soundfont_t *sf, soundfont_voice_info_t *avp)
{
	snd_sf_sample_t *sample;

	sample = find_sample(sf, avp->sample);
	if (sample == NULL)
		return NULL;

	/* add in the actual sample offsets:
	 * The voice_info addresses define only the relative offset
	 * from sample pointers.  Here we calculate the actual DRAM
	 * offset from sample pointers.
	 */
	avp->start += sample->v.start;
	avp->end += sample->v.end;
	avp->loopstart += sample->v.loopstart;
	avp->loopend += sample->v.loopend;

	/* copy mode flags */
	avp->sample_mode = sample->v.mode_flags;

	return sample;
}

/* find the sample pointer with the given id in the soundfont */
static snd_sf_sample_t *
find_sample(snd_soundfont_t *sf, int sample_id)
{
	snd_sf_sample_t *p;

	if (sf == NULL)
		return NULL;

	for (p = sf->samples; p; p = p->next) {
		if (p->v.sample == sample_id)
			return p;
	}
	return NULL;
}


/*
 * Load sample information, this can include data to be loaded onto
 * the soundcard.  It can also just be a pointer into soundcard ROM.
 * If there is data it will be written to the soundcard via the callback
 * routine.
 */
static int
load_data(snd_sf_list_t *sflist, const void __user *data, long count)
{
	snd_soundfont_t *sf;
	soundfont_sample_info_t sample_info;
	snd_sf_sample_t *sp;
	long off;

	/* patch must be opened */
	if ((sf = sflist->currsf) == NULL)
		return -EINVAL;

	if (is_special_type(sf->type))
		return -EINVAL;

	if (copy_from_user(&sample_info, data, sizeof(sample_info)))
		return -EFAULT;

	off = sizeof(sample_info);

	if (sample_info.size != (count-off)/2)
		return -EINVAL;

	/* Check for dup */
	if (find_sample(sf, sample_info.sample)) {
		/* if shared sample, skip this data */
		if (sf->type & SNDRV_SFNT_PAT_SHARED)
			return 0;
		return -EINVAL;
	}

	/* Allocate a new sample structure */
	if ((sp = sf_sample_new(sflist, sf)) == NULL)
		return -ENOMEM;

	sp->v = sample_info;
	sp->v.sf_id = sf->id;
	sp->v.dummy = 0;
	sp->v.truesize = sp->v.size;

	/*
	 * If there is wave data then load it.
	 */
	if (sp->v.size > 0) {
		int  rc;
		rc = sflist->callback.sample_new
			(sflist->callback.private_data, sp, sflist->memhdr,
			 data + off, count - off);
		if (rc < 0) {
			sf_sample_delete(sflist, sf, sp);
			return rc;
		}
		sflist->mem_used += sp->v.truesize;
	}

	return count;
}


/* log2_tbl[i] = log2(i+128) * 0x10000 */
static int log_tbl[129] = {
	0x70000, 0x702df, 0x705b9, 0x7088e, 0x70b5d, 0x70e26, 0x710eb, 0x713aa,
	0x71663, 0x71918, 0x71bc8, 0x71e72, 0x72118, 0x723b9, 0x72655, 0x728ed,
	0x72b80, 0x72e0e, 0x73098, 0x7331d, 0x7359e, 0x7381b, 0x73a93, 0x73d08,
	0x73f78, 0x741e4, 0x7444c, 0x746b0, 0x74910, 0x74b6c, 0x74dc4, 0x75019,
	0x75269, 0x754b6, 0x75700, 0x75946, 0x75b88, 0x75dc7, 0x76002, 0x7623a,
	0x7646e, 0x766a0, 0x768cd, 0x76af8, 0x76d1f, 0x76f43, 0x77164, 0x77382,
	0x7759d, 0x777b4, 0x779c9, 0x77bdb, 0x77dea, 0x77ff5, 0x781fe, 0x78404,
	0x78608, 0x78808, 0x78a06, 0x78c01, 0x78df9, 0x78fef, 0x791e2, 0x793d2,
	0x795c0, 0x797ab, 0x79993, 0x79b79, 0x79d5d, 0x79f3e, 0x7a11d, 0x7a2f9,
	0x7a4d3, 0x7a6ab, 0x7a880, 0x7aa53, 0x7ac24, 0x7adf2, 0x7afbe, 0x7b188,
	0x7b350, 0x7b515, 0x7b6d8, 0x7b899, 0x7ba58, 0x7bc15, 0x7bdd0, 0x7bf89,
	0x7c140, 0x7c2f5, 0x7c4a7, 0x7c658, 0x7c807, 0x7c9b3, 0x7cb5e, 0x7cd07,
	0x7ceae, 0x7d053, 0x7d1f7, 0x7d398, 0x7d538, 0x7d6d6, 0x7d872, 0x7da0c,
	0x7dba4, 0x7dd3b, 0x7ded0, 0x7e063, 0x7e1f4, 0x7e384, 0x7e512, 0x7e69f,
	0x7e829, 0x7e9b3, 0x7eb3a, 0x7ecc0, 0x7ee44, 0x7efc7, 0x7f148, 0x7f2c8,
	0x7f446, 0x7f5c2, 0x7f73d, 0x7f8b7, 0x7fa2f, 0x7fba5, 0x7fd1a, 0x7fe8d,
	0x80000,
};

/* convert from linear to log value
 *
 * conversion: value = log2(amount / base) * ratio
 *
 * argument:
 *   amount = linear value (unsigned, 32bit max)
 *   offset = base offset (:= log2(base) * 0x10000)
 *   ratio = division ratio
 *
 */
int
snd_sf_linear_to_log(unsigned int amount, int offset, int ratio)
{
	int v;
	int s, low, bit;
	
	if (amount < 2)
		return 0;
	for (bit = 0; ! (amount & 0x80000000L); bit++)
		amount <<= 1;
	s = (amount >> 24) & 0x7f;
	low = (amount >> 16) & 0xff;
	/* linear approxmimation by lower 8 bit */
	v = (log_tbl[s + 1] * low + log_tbl[s] * (0x100 - low)) >> 8;
	v -= offset;
	v = (v * ratio) >> 16;
	v += (24 - bit) * ratio;
	return v;
}

#define OFFSET_MSEC		653117		/* base = 1000 */
#define OFFSET_ABSCENT		851781		/* base = 8176 */
#define OFFSET_SAMPLERATE	1011119		/* base = 44100 */

#define ABSCENT_RATIO		1200
#define TIMECENT_RATIO		1200
#define SAMPLERATE_RATIO	4096

/*
 * mHz to abscent
 * conversion: abscent = log2(MHz / 8176) * 1200
 */
static int
freq_to_note(int mhz)
{
	return snd_sf_linear_to_log(mhz, OFFSET_ABSCENT, ABSCENT_RATIO);
}

/* convert Hz to AWE32 rate offset:
 * sample pitch offset for the specified sample rate
 * rate=44100 is no offset, each 4096 is 1 octave (twice).
 * eg, when rate is 22050, this offset becomes -4096.
 *
 * conversion: offset = log2(Hz / 44100) * 4096
 */
static int
calc_rate_offset(int hz)
{
	return snd_sf_linear_to_log(hz, OFFSET_SAMPLERATE, SAMPLERATE_RATIO);
}


/* calculate GUS envelope time */
static int
calc_gus_envelope_time(int rate, int start, int end)
{
	int r, p, t;
	r = (3 - ((rate >> 6) & 3)) * 3;
	p = rate & 0x3f;
	t = end - start;
	if (t < 0) t = -t;
	if (13 > r)
		t = t << (13 - r);
	else
		t = t >> (r - 13);
	return (t * 10) / (p * 441);
}

/* convert envelope time parameter to soundfont parameters */

/* attack & decay/release time table (msec) */
static short attack_time_tbl[128] = {
32767, 32767, 5989, 4235, 2994, 2518, 2117, 1780, 1497, 1373, 1259, 1154, 1058, 970, 890, 816,
707, 691, 662, 634, 607, 581, 557, 533, 510, 489, 468, 448, 429, 411, 393, 377,
361, 345, 331, 317, 303, 290, 278, 266, 255, 244, 234, 224, 214, 205, 196, 188,
180, 172, 165, 158, 151, 145, 139, 133, 127, 122, 117, 112, 107, 102, 98, 94,
90, 86, 82, 79, 75, 72, 69, 66, 63, 61, 58, 56, 53, 51, 49, 47,
45, 43, 41, 39, 37, 36, 34, 33, 31, 30, 29, 28, 26, 25, 24, 23,
22, 21, 20, 19, 19, 18, 17, 16, 16, 15, 15, 14, 13, 13, 12, 12,
11, 11, 10, 10, 10, 9, 9, 8, 8, 8, 8, 7, 7, 7, 6, 0,
};

static short decay_time_tbl[128] = {
32767, 32767, 22614, 15990, 11307, 9508, 7995, 6723, 5653, 5184, 4754, 4359, 3997, 3665, 3361, 3082,
2828, 2765, 2648, 2535, 2428, 2325, 2226, 2132, 2042, 1955, 1872, 1793, 1717, 1644, 1574, 1507,
1443, 1382, 1324, 1267, 1214, 1162, 1113, 1066, 978, 936, 897, 859, 822, 787, 754, 722,
691, 662, 634, 607, 581, 557, 533, 510, 489, 468, 448, 429, 411, 393, 377, 361,
345, 331, 317, 303, 290, 278, 266, 255, 244, 234, 224, 214, 205, 196, 188, 180,
172, 165, 158, 151, 145, 139, 133, 127, 122, 117, 112, 107, 102, 98, 94, 90,
86, 82, 79, 75, 72, 69, 66, 63, 61, 58, 56, 53, 51, 49, 47, 45,
43, 41, 39, 37, 36, 34, 33, 31, 30, 29, 28, 26, 25, 24, 23, 22,
};

/* delay time = 0x8000 - msec/92 */
int
snd_sf_calc_parm_hold(int msec)
{
	int val = (0x7f * 92 - msec) / 92;
	if (val < 1) val = 1;
	if (val >= 126) val = 126;
	return val;
}

/* search an index for specified time from given time table */
static int
calc_parm_search(int msec, short *table)
{
	int left = 1, right = 127, mid;
	while (left < right) {
		mid = (left + right) / 2;
		if (msec < (int)table[mid])
			left = mid + 1;
		else
			right = mid;
	}
	return left;
}

/* attack time: search from time table */
int
snd_sf_calc_parm_attack(int msec)
{
	return calc_parm_search(msec, attack_time_tbl);
}

/* decay/release time: search from time table */
int
snd_sf_calc_parm_decay(int msec)
{
	return calc_parm_search(msec, decay_time_tbl);
}

int snd_sf_vol_table[128] = {
	255,111,95,86,79,74,70,66,63,61,58,56,54,52,50,49,
	47,46,45,43,42,41,40,39,38,37,36,35,34,34,33,32,
	31,31,30,29,29,28,27,27,26,26,25,24,24,23,23,22,
	22,21,21,21,20,20,19,19,18,18,18,17,17,16,16,16,
	15,15,15,14,14,14,13,13,13,12,12,12,11,11,11,10,
	10,10,10,9,9,9,8,8,8,8,7,7,7,7,6,6,
	6,6,5,5,5,5,5,4,4,4,4,3,3,3,3,3,
	2,2,2,2,2,1,1,1,1,1,0,0,0,0,0,0,
};


#define calc_gus_sustain(val)  (0x7f - snd_sf_vol_table[(val)/2])
#define calc_gus_attenuation(val)	snd_sf_vol_table[(val)/2]

/* load GUS patch */
static int
load_guspatch(snd_sf_list_t *sflist, const char __user *data, long count, int client)
{
	struct patch_info patch;
	snd_soundfont_t *sf;
	snd_sf_zone_t *zone;
	snd_sf_sample_t *smp;
	int note, sample_id;
	int rc;

	if (count < (long)sizeof(patch)) {
		snd_printk("patch record too small %ld\n", count);
		return -EINVAL;
	}
	if (copy_from_user(&patch, data, sizeof(patch)))
		return -EFAULT;
	
	count -= sizeof(patch);
	data += sizeof(patch);

	sf = newsf(sflist, SNDRV_SFNT_PAT_TYPE_GUS|SNDRV_SFNT_PAT_SHARED, NULL);
	if (sf == NULL)
		return -ENOMEM;
	if ((smp = sf_sample_new(sflist, sf)) == NULL)
		return -ENOMEM;
	sample_id = sflist->sample_counter;
	smp->v.sample = sample_id;
	smp->v.start = 0;
	smp->v.end = patch.len;
	smp->v.loopstart = patch.loop_start;
	smp->v.loopend = patch.loop_end;
	smp->v.size = patch.len;

	/* set up mode flags */
	smp->v.mode_flags = 0;
	if (!(patch.mode & WAVE_16_BITS))
		smp->v.mode_flags |= SNDRV_SFNT_SAMPLE_8BITS;
	if (patch.mode & WAVE_UNSIGNED)
		smp->v.mode_flags |= SNDRV_SFNT_SAMPLE_UNSIGNED;
	smp->v.mode_flags |= SNDRV_SFNT_SAMPLE_NO_BLANK;
	if (!(patch.mode & (WAVE_LOOPING|WAVE_BIDIR_LOOP|WAVE_LOOP_BACK)))
		smp->v.mode_flags |= SNDRV_SFNT_SAMPLE_SINGLESHOT;
	if (patch.mode & WAVE_BIDIR_LOOP)
		smp->v.mode_flags |= SNDRV_SFNT_SAMPLE_BIDIR_LOOP;
	if (patch.mode & WAVE_LOOP_BACK)
		smp->v.mode_flags |= SNDRV_SFNT_SAMPLE_REVERSE_LOOP;

	if (patch.mode & WAVE_16_BITS) {
		/* convert to word offsets */
		smp->v.size /= 2;
		smp->v.end /= 2;
		smp->v.loopstart /= 2;
		smp->v.loopend /= 2;
	}
	/*smp->v.loopend++;*/

	smp->v.dummy = 0;
	smp->v.truesize = 0;
	smp->v.sf_id = sf->id;

	/* set up voice info */
	if ((zone = sf_zone_new(sflist, sf)) == NULL) {
		sf_sample_delete(sflist, sf, smp);
		return -ENOMEM;
	}

	/*
	 * load wave data
	 */
	if (sflist->callback.sample_new) {
		rc = sflist->callback.sample_new
			(sflist->callback.private_data, smp, sflist->memhdr, data, count);
		if (rc < 0) {
			sf_sample_delete(sflist, sf, smp);
			return rc;
		}
		/* memory offset is updated after */
	}

	/* update the memory offset here */
	sflist->mem_used += smp->v.truesize;

	zone->v.sample = sample_id; /* the last sample */
	zone->v.rate_offset = calc_rate_offset(patch.base_freq);
	note = freq_to_note(patch.base_note);
	zone->v.root = note / 100;
	zone->v.tune = -(note % 100);
	zone->v.low = (freq_to_note(patch.low_note) + 99) / 100;
	zone->v.high = freq_to_note(patch.high_note) / 100;
	/* panning position; -128 - 127 => 0-127 */
	zone->v.pan = (patch.panning + 128) / 2;
#if 0
	snd_printk("gus: basefrq=%d (ofs=%d) root=%d,tune=%d, range:%d-%d\n",
		   (int)patch.base_freq, zone->v.rate_offset,
		   zone->v.root, zone->v.tune, zone->v.low, zone->v.high);
#endif

	/* detuning is ignored */
	/* 6points volume envelope */
	if (patch.mode & WAVE_ENVELOPES) {
		int attack, hold, decay, release;
		attack = calc_gus_envelope_time
			(patch.env_rate[0], 0, patch.env_offset[0]);
		hold = calc_gus_envelope_time
			(patch.env_rate[1], patch.env_offset[0],
			 patch.env_offset[1]);
		decay = calc_gus_envelope_time
			(patch.env_rate[2], patch.env_offset[1],
			 patch.env_offset[2]);
		release = calc_gus_envelope_time
			(patch.env_rate[3], patch.env_offset[1],
			 patch.env_offset[4]);
		release += calc_gus_envelope_time
			(patch.env_rate[4], patch.env_offset[3],
			 patch.env_offset[4]);
		release += calc_gus_envelope_time
			(patch.env_rate[5], patch.env_offset[4],
			 patch.env_offset[5]);
		zone->v.parm.volatkhld = 
			(snd_sf_calc_parm_hold(hold) << 8) |
			snd_sf_calc_parm_attack(attack);
		zone->v.parm.voldcysus = (calc_gus_sustain(patch.env_offset[2]) << 8) |
			snd_sf_calc_parm_decay(decay);
		zone->v.parm.volrelease = 0x8000 | snd_sf_calc_parm_decay(release);
		zone->v.attenuation = calc_gus_attenuation(patch.env_offset[0]);
#if 0
		snd_printk("gus: atkhld=%x, dcysus=%x, volrel=%x, att=%d\n",
			   zone->v.parm.volatkhld,
			   zone->v.parm.voldcysus,
			   zone->v.parm.volrelease,
			   zone->v.attenuation);
#endif
	}

	/* fast release */
	if (patch.mode & WAVE_FAST_RELEASE) {
		zone->v.parm.volrelease = 0x807f;
	}

	/* tremolo effect */
	if (patch.mode & WAVE_TREMOLO) {
		int rate = (patch.tremolo_rate * 1000 / 38) / 42;
		zone->v.parm.tremfrq = ((patch.tremolo_depth / 2) << 8) | rate;
	}
	/* vibrato effect */
	if (patch.mode & WAVE_VIBRATO) {
		int rate = (patch.vibrato_rate * 1000 / 38) / 42;
		zone->v.parm.fm2frq2 = ((patch.vibrato_depth / 6) << 8) | rate;
	}
	
	/* scale_freq, scale_factor, volume, and fractions not implemented */

	if (!(smp->v.mode_flags & SNDRV_SFNT_SAMPLE_SINGLESHOT))
		zone->v.mode = SNDRV_SFNT_MODE_LOOPING;
	else
		zone->v.mode = 0;

	/* append to the tail of the list */
	/*zone->bank = ctrls[AWE_MD_GUS_BANK];*/
	zone->bank = 0;
	zone->instr = patch.instr_no;
	zone->mapped = 0;
	zone->v.sf_id = sf->id;

	zone->sample = set_sample(sf, &zone->v);

	/* rebuild preset now */
	add_preset(sflist, zone);

	return 0;
}

/* load GUS patch */
int
snd_soundfont_load_guspatch(snd_sf_list_t *sflist, const char __user *data,
			    long count, int client)
{
	int rc;
	lock_preset(sflist);
	rc = load_guspatch(sflist, data, count, client);
	unlock_preset(sflist);
	return rc;
}


/*
 * Rebuild the preset table.  This is like a hash table in that it allows
 * quick access to the zone information.  For each preset there are zone
 * structures linked by next_instr and by next_zone.  Former is the whole
 * link for this preset, and latter is the link for zone (i.e. instrument/
 * bank/key combination).
 */
static void
rebuild_presets(snd_sf_list_t *sflist)
{
	snd_soundfont_t *sf;
	snd_sf_zone_t *cur;

	/* clear preset table */
	memset(sflist->presets, 0, sizeof(sflist->presets));

	/* search all fonts and insert each font */
	for (sf = sflist->fonts; sf; sf = sf->next) {
		for (cur = sf->zones; cur; cur = cur->next) {
			if (! cur->mapped && cur->sample == NULL) {
				/* try again to search the corresponding sample */
				cur->sample = set_sample(sf, &cur->v);
				if (cur->sample == NULL)
					continue;
			}

			add_preset(sflist, cur);
		}
	}
}


/*
 * add the given zone to preset table
 */
static void
add_preset(snd_sf_list_t *sflist, snd_sf_zone_t *cur)
{
	snd_sf_zone_t *zone;
	int index;

	zone = search_first_zone(sflist, cur->bank, cur->instr, cur->v.low);
	if (zone && zone->v.sf_id != cur->v.sf_id) {
		/* different instrument was already defined */
		snd_sf_zone_t *p;
		/* compare the allocated time */
		for (p = zone; p; p = p->next_zone) {
			if (p->counter > cur->counter)
				/* the current is older.. skipped */
				return;
		}
		/* remove old zones */
		delete_preset(sflist, zone);
		zone = NULL; /* do not forget to clear this! */
	}

	/* prepend this zone */
	if ((index = get_index(cur->bank, cur->instr, cur->v.low)) < 0)
		return;
	cur->next_zone = zone; /* zone link */
	cur->next_instr = sflist->presets[index]; /* preset table link */
	sflist->presets[index] = cur;
}

/*
 * delete the given zones from preset_table
 */
static void
delete_preset(snd_sf_list_t *sflist, snd_sf_zone_t *zp)
{
	int index;
	snd_sf_zone_t *p;

	if ((index = get_index(zp->bank, zp->instr, zp->v.low)) < 0)
		return;
	for (p = sflist->presets[index]; p; p = p->next_instr) {
		while (p->next_instr == zp) {
			p->next_instr = zp->next_instr;
			zp = zp->next_zone;
			if (zp == NULL)
				return;
		}
	}
}


/*
 * Search matching zones from preset table.
 * The note can be rewritten by preset mapping (alias).
 * The found zones are stored on 'table' array.  max_layers defines
 * the maximum number of elements in this array.
 * This function returns the number of found zones.  0 if not found.
 */
int
snd_soundfont_search_zone(snd_sf_list_t *sflist, int *notep, int vel,
			  int preset, int bank,
			  int def_preset, int def_bank,
			  snd_sf_zone_t **table, int max_layers)
{
	int nvoices;
	unsigned long flags;

	/* this function is supposed to be called atomically,
	 * so we check the lock.  if it's busy, just returns 0 to
	 * tell the caller the busy state
	 */
	spin_lock_irqsave(&sflist->lock, flags);
	if (sflist->presets_locked) {
		spin_unlock_irqrestore(&sflist->lock, flags);
		return 0;
	}
	nvoices = search_zones(sflist, notep, vel, preset, bank, table, max_layers, 0);
	if (! nvoices) {
		if (preset != def_preset || bank != def_bank)
			nvoices = search_zones(sflist, notep, vel, def_preset, def_bank, table, max_layers, 0);
	}
	spin_unlock_irqrestore(&sflist->lock, flags);
	return nvoices;
}


/*
 * search the first matching zone
 */
static snd_sf_zone_t *
search_first_zone(snd_sf_list_t *sflist, int bank, int preset, int key)
{
	int index;
	snd_sf_zone_t *zp;

	if ((index = get_index(bank, preset, key)) < 0)
		return NULL;
	for (zp = sflist->presets[index]; zp; zp = zp->next_instr) {
		if (zp->instr == preset && zp->bank == bank)
			return zp;
	}
	return NULL;
}


/*
 * search matching zones from sflist.  can be called recursively.
 */
static int
search_zones(snd_sf_list_t *sflist, int *notep, int vel, int preset, int bank, snd_sf_zone_t **table, int max_layers, int level)
{
	snd_sf_zone_t *zp;
	int nvoices;

	zp = search_first_zone(sflist, bank, preset, *notep);
	nvoices = 0;
	for (; zp; zp = zp->next_zone) {
		if (*notep >= zp->v.low && *notep <= zp->v.high &&
		    vel >= zp->v.vellow && vel <= zp->v.velhigh) {
			if (zp->mapped) {
				/* search preset mapping (aliasing) */
				int key = zp->v.fixkey;
				preset = zp->v.start;
				bank = zp->v.end;

				if (level > 5) /* too deep alias level */
					return 0;
				if (key < 0)
					key = *notep;
				nvoices = search_zones(sflist, &key, vel,
						       preset, bank, table,
						       max_layers, level + 1);
				if (nvoices > 0)
					*notep = key;
				break;
			}
			table[nvoices++] = zp;
			if (nvoices >= max_layers)
				break;
		}
	}

	return nvoices;
}


/* calculate the index of preset table:
 * drums are mapped from 128 to 255 according to its note key.
 * other instruments are mapped from 0 to 127.
 * if the index is out of range, return -1.
 */
static int
get_index(int bank, int instr, int key)
{
	int index;
	if (SF_IS_DRUM_BANK(bank))
		index = key + SF_MAX_INSTRUMENTS;
	else
		index = instr;
	index = index % SF_MAX_PRESETS;
	if (index < 0)
		return -1;
	return index;
}

/*
 * Initialise the sflist structure.
 */
static void
snd_sf_init(snd_sf_list_t *sflist)
{
	memset(sflist->presets, 0, sizeof(sflist->presets));

	sflist->mem_used = 0;
	sflist->currsf = NULL;
	sflist->open_client = -1;
	sflist->fonts = NULL;
	sflist->fonts_size = 0;
	sflist->zone_counter = 0;
	sflist->sample_counter = 0;
	sflist->zone_locked = 0;
	sflist->sample_locked = 0;
}

/*
 * Release all list records
 */
static void
snd_sf_clear(snd_sf_list_t *sflist)
{
	snd_soundfont_t *sf, *nextsf;
	snd_sf_zone_t *zp, *nextzp;
	snd_sf_sample_t *sp, *nextsp;

	for (sf = sflist->fonts; sf; sf = nextsf) {
		nextsf = sf->next;
		for (zp = sf->zones; zp; zp = nextzp) {
			nextzp = zp->next;
			kfree(zp);
		}
		for (sp = sf->samples; sp; sp = nextsp) {
			nextsp = sp->next;
			if (sflist->callback.sample_free)
				sflist->callback.sample_free(sflist->callback.private_data, sp, sflist->memhdr);
			kfree(sp);
		}
		kfree(sf);
	}

	snd_sf_init(sflist);
}


/*
 * Create a new sflist structure
 */
snd_sf_list_t *
snd_sf_new(snd_sf_callback_t *callback, snd_util_memhdr_t *hdr)
{
	snd_sf_list_t *sflist;

	if ((sflist = kcalloc(1, sizeof(*sflist), GFP_KERNEL)) == NULL)
		return NULL;

	init_MUTEX(&sflist->presets_mutex);
	spin_lock_init(&sflist->lock);
	sflist->memhdr = hdr;

	if (callback)
		sflist->callback = *callback;

	snd_sf_init(sflist);
	return sflist;
}


/*
 * Free everything allocated off the sflist structure.
 */
void
snd_sf_free(snd_sf_list_t *sflist)
{
	if (sflist == NULL)
		return;
	
	lock_preset(sflist);
	if (sflist->callback.sample_reset)
		sflist->callback.sample_reset(sflist->callback.private_data);
	snd_sf_clear(sflist);
	unlock_preset(sflist);

	kfree(sflist);
}

/*
 * Remove all samples
 * The soundcard should be silet before calling this function.
 */
int
snd_soundfont_remove_samples(snd_sf_list_t *sflist)
{
	lock_preset(sflist);
	if (sflist->callback.sample_reset)
		sflist->callback.sample_reset(sflist->callback.private_data);
	snd_sf_clear(sflist);
	unlock_preset(sflist);

	return 0;
}

/*
 * Remove unlocked samples.
 * The soundcard should be silent before calling this function.
 */
int
snd_soundfont_remove_unlocked(snd_sf_list_t *sflist)
{
	snd_soundfont_t *sf;
	snd_sf_zone_t *zp, *nextzp;
	snd_sf_sample_t *sp, *nextsp;

	lock_preset(sflist);

	if (sflist->callback.sample_reset)
		sflist->callback.sample_reset(sflist->callback.private_data);

	/* to be sure */
	memset(sflist->presets, 0, sizeof(sflist->presets));

	for (sf = sflist->fonts; sf; sf = sf->next) {
		for (zp = sf->zones; zp; zp = nextzp) {
			if (zp->counter < sflist->zone_locked)
				break;
			nextzp = zp->next;
			sf->zones = nextzp;
			kfree(zp);
		}

		for (sp = sf->samples; sp; sp = nextsp) {
			if (sp->counter < sflist->sample_locked)
				break;
			nextsp = sp->next;
			sf->samples = nextsp;
			sflist->mem_used -= sp->v.truesize;
			if (sflist->callback.sample_free)
				sflist->callback.sample_free(sflist->callback.private_data, sp, sflist->memhdr);
			kfree(sp);
		}
	}

	sflist->zone_counter = sflist->zone_locked;
	sflist->sample_counter = sflist->sample_locked;

	rebuild_presets(sflist);

	unlock_preset(sflist);
	return 0;
}

