/*
 *  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 <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(struct snd_sf_list *sflist, const char __user *data,
		      int count, int client);
static struct snd_soundfont *newsf(struct snd_sf_list *sflist, int type, char *name);
static int is_identical_font(struct snd_soundfont *sf, int type, unsigned char *name);
static int close_patch(struct snd_sf_list *sflist);
static int probe_data(struct snd_sf_list *sflist, int sample_id);
static void set_zone_counter(struct snd_sf_list *sflist,
			     struct snd_soundfont *sf, struct snd_sf_zone *zp);
static struct snd_sf_zone *sf_zone_new(struct snd_sf_list *sflist,
				       struct snd_soundfont *sf);
static void set_sample_counter(struct snd_sf_list *sflist,
			       struct snd_soundfont *sf, struct snd_sf_sample *sp);
static struct snd_sf_sample *sf_sample_new(struct snd_sf_list *sflist,
					   struct snd_soundfont *sf);
static void sf_sample_delete(struct snd_sf_list *sflist,
			     struct snd_soundfont *sf, struct snd_sf_sample *sp);
static int load_map(struct snd_sf_list *sflist, const void __user *data, int count);
static int load_info(struct snd_sf_list *sflist, const void __user *data, long count);
static int remove_info(struct snd_sf_list *sflist, struct snd_soundfont *sf,
		       int bank, int instr);
static void init_voice_info(struct soundfont_voice_info *avp);
static void init_voice_parm(struct soundfont_voice_parm *pp);
static struct snd_sf_sample *set_sample(struct snd_soundfont *sf,
					struct soundfont_voice_info *avp);
static struct snd_sf_sample *find_sample(struct snd_soundfont *sf, int sample_id);
static int load_data(struct snd_sf_list *sflist, const void __user *data, long count);
static void rebuild_presets(struct snd_sf_list *sflist);
static void add_preset(struct snd_sf_list *sflist, struct snd_sf_zone *cur);
static void delete_preset(struct snd_sf_list *sflist, struct snd_sf_zone *zp);
static struct snd_sf_zone *search_first_zone(struct snd_sf_list *sflist,
					     int bank, int preset, int key);
static int search_zones(struct snd_sf_list *sflist, int *notep, int vel,
			int preset, int bank, struct snd_sf_zone **table,
			int max_layers, int level);
static int get_index(int bank, int instr, int key);
static void snd_sf_init(struct snd_sf_list *sflist);
static void snd_sf_clear(struct snd_sf_list *sflist);

/*
 * lock access to sflist
 */
static void
lock_preset(struct snd_sf_list *sflist)
{
	unsigned long flags;
	mutex_lock(&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(struct snd_sf_list *sflist)
{
	unsigned long flags;
	spin_lock_irqsave(&sflist->lock, flags);
	sflist->presets_locked = 0;
	spin_unlock_irqrestore(&sflist->lock, flags);
	mutex_unlock(&sflist->presets_mutex);
}


/*
 * close the patch if the patch was opened by this client.
 */
int
snd_soundfont_close_check(struct snd_sf_list *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(struct snd_sf_list *sflist, const void __user *data,
		   long count, int client)
{
	struct soundfont_patch_info patch;
	unsigned long flags;
	int  rc;

	if (count < (long)sizeof(patch)) {
		snd_printk(KERN_ERR "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(KERN_ERR "The wrong kind of patch %x\n", patch.key);
		return -EINVAL;
	}
	if (count < patch.len) {
		snd_printk(KERN_ERR "Patch too short %ld, need %d\n",
			   count, patch.len);
		return -EINVAL;
	}
	if (patch.len < 0) {
		snd_printk(KERN_ERR "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(KERN_ERR "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(struct snd_sf_list *sflist, const char __user *data,
	   int count, int client)
{
	struct soundfont_open_parm parm;
	struct snd_soundfont *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 struct snd_soundfont *
newsf(struct snd_sf_list *sflist, int type, char *name)
{
	struct snd_soundfont *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 = kzalloc(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(struct snd_soundfont *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(struct snd_sf_list *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(struct snd_sf_list *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(struct snd_sf_list *sflist, struct snd_soundfont *sf,
		 struct snd_sf_zone *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 struct snd_sf_zone *
sf_zone_new(struct snd_sf_list *sflist, struct snd_soundfont *sf)
{
	struct snd_sf_zone *zp;

	if ((zp = kzalloc(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(struct snd_sf_list *sflist, struct snd_soundfont *sf,
		   struct snd_sf_sample *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 struct snd_sf_sample *
sf_sample_new(struct snd_sf_list *sflist, struct snd_soundfont *sf)
{
	struct snd_sf_sample *sp;

	if ((sp = kzalloc(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(struct snd_sf_list *sflist, struct snd_soundfont *sf,
		 struct snd_sf_sample *sp)
{
	/* only last sample is accepted */
	if (sp == sf->samples) {
		sf->samples = sp->next;
		kfree(sp);
	}
}


/* load voice map */
static int
load_map(struct snd_sf_list *sflist, const void __user *data, int count)
{
	struct snd_sf_zone *zp, *prevp;
	struct snd_soundfont *sf;
	struct soundfont_voice_map 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(struct snd_sf_list *sflist, struct snd_soundfont *sf,
	    int bank, int instr)
{
	struct snd_sf_zone *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(struct snd_sf_list *sflist, const void __user *data, long count)
{
	struct snd_soundfont *sf;
	struct snd_sf_zone *zone;
	struct soundfont_voice_rec_hdr 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(KERN_ERR "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(KERN_ERR "Soundfont error: Illegal voice number %d\n",
		       hdr.nvoices);
		return -EINVAL;
	}

	if (count < (long)sizeof(struct soundfont_voice_info) * hdr.nvoices) {
		printk(KERN_ERR "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++) {
		struct snd_sf_zone 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(struct soundfont_voice_info *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(struct soundfont_voice_parm *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 struct snd_sf_sample *
set_sample(struct snd_soundfont *sf, struct soundfont_voice_info *avp)
{
	struct snd_sf_sample *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 struct snd_sf_sample *
find_sample(struct snd_soundfont *sf, int sample_id)
{
	struct snd_sf_sample *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(struct snd_sf_list *sflist, const void __user *data, long count)
{
	struct snd_soundfont *sf;
	struct soundfont_sample_info sample_info;
	struct snd_sf_sample *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;
}

EXPORT_SYMBOL(snd_sf_linear_to_log);


#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(struct snd_sf_list *sflist, const char __user *data,
	      long count, int client)
{
	struct patch_info patch;
	struct snd_soundfont *sf;
	struct snd_sf_zone *zone;
	struct snd_sf_sample *smp;
	int note, sample_id;
	int rc;

	if (count < (long)sizeof(patch)) {
		snd_printk(KERN_ERR "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(KERN_DEBUG
		   "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(KERN_DEBUG
			   "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(struct snd_sf_list *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(struct snd_sf_list *sflist)
{
	struct snd_soundfont *sf;
	struct snd_sf_zone *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(struct snd_sf_list *sflist, struct snd_sf_zone *cur)
{
	struct snd_sf_zone *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 */
		struct snd_sf_zone *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(struct snd_sf_list *sflist, struct snd_sf_zone *zp)
{
	int index;
	struct snd_sf_zone *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(struct snd_sf_list *sflist, int *notep, int vel,
			  int preset, int bank,
			  int def_preset, int def_bank,
			  struct snd_sf_zone **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 struct snd_sf_zone *
search_first_zone(struct snd_sf_list *sflist, int bank, int preset, int key)
{
	int index;
	struct snd_sf_zone *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(struct snd_sf_list *sflist, int *notep, int vel,
	     int preset, int bank, struct snd_sf_zone **table,
	     int max_layers, int level)
{
	struct snd_sf_zone *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(struct snd_sf_list *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(struct snd_sf_list *sflist)
{
	struct snd_soundfont *sf, *nextsf;
	struct snd_sf_zone *zp, *nextzp;
	struct snd_sf_sample *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
 */
struct snd_sf_list *
snd_sf_new(struct snd_sf_callback *callback, struct snd_util_memhdr *hdr)
{
	struct snd_sf_list *sflist;

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

	mutex_init(&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(struct snd_sf_list *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(struct snd_sf_list *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(struct snd_sf_list *sflist)
{
	struct snd_soundfont *sf;
	struct snd_sf_zone *zp, *nextzp;
	struct snd_sf_sample *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;
}
