// SPDX-License-Identifier: GPL-2.0-or-later
/*
 *  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>
 */
/*
 * 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 <linux/uaccess.h>
#include <linux/slab.h>
#include <linux/export.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 parameters 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;

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

	init_voice_info(&zp->v);

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


/*
 * increment sample counter
 */
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;

	sp = kzalloc(sizeof(*sp), GFP_KERNEL);
	if (!sp)
		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 */
	zp = sf_zone_new(sflist, sf);
	if (!zp)
		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 */
	sf = sflist->currsf;
	if (!sf)
		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 */
		zone = sf_zone_new(sflist, sf);
		if (!zone)
			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 */
	sf = sflist->currsf;
	if (!sf)
		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 */
	sp = sf_sample_new(sflist, sf);
	if (!sp)
		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 const 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 approximation 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;
	if (!p)
		p = 1;
	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 const 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 const 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, const 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;
	smp = sf_sample_new(sflist, sf);
	if (!smp)
		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 */
	zone = sf_zone_new(sflist, sf);
	if (!zone) {
		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);
			kfree(zone);
			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 */
	index = get_index(cur->bank, cur->instr, cur->v.low);
	if (index < 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;

	index = get_index(zp->bank, zp->instr, zp->v.low);
	if (index < 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;

	index = get_index(bank, preset, key);
	if (index < 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;

	sflist = kzalloc(sizeof(*sflist), GFP_KERNEL);
	if (!sflist)
		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 silent 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;
}
