cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

soundfont.c (37837B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 *  Soundfont generic routines.
      4 *	It is intended that these should be used by any driver that is willing
      5 *	to accept soundfont patches.
      6 *
      7 *  Copyright (C) 1999 Steve Ratcliffe
      8 *  Copyright (c) 1999-2000 Takashi Iwai <tiwai@suse.de>
      9 */
     10/*
     11 * Deal with reading in of a soundfont.  Code follows the OSS way
     12 * of doing things so that the old sfxload utility can be used.
     13 * Everything may change when there is an alsa way of doing things.
     14 */
     15#include <linux/uaccess.h>
     16#include <linux/slab.h>
     17#include <linux/export.h>
     18#include <sound/core.h>
     19#include <sound/soundfont.h>
     20#include <sound/seq_oss_legacy.h>
     21
     22/* Prototypes for static functions */
     23
     24static int open_patch(struct snd_sf_list *sflist, const char __user *data,
     25		      int count, int client);
     26static struct snd_soundfont *newsf(struct snd_sf_list *sflist, int type, char *name);
     27static int is_identical_font(struct snd_soundfont *sf, int type, unsigned char *name);
     28static int close_patch(struct snd_sf_list *sflist);
     29static int probe_data(struct snd_sf_list *sflist, int sample_id);
     30static void set_zone_counter(struct snd_sf_list *sflist,
     31			     struct snd_soundfont *sf, struct snd_sf_zone *zp);
     32static struct snd_sf_zone *sf_zone_new(struct snd_sf_list *sflist,
     33				       struct snd_soundfont *sf);
     34static void set_sample_counter(struct snd_sf_list *sflist,
     35			       struct snd_soundfont *sf, struct snd_sf_sample *sp);
     36static struct snd_sf_sample *sf_sample_new(struct snd_sf_list *sflist,
     37					   struct snd_soundfont *sf);
     38static void sf_sample_delete(struct snd_sf_list *sflist,
     39			     struct snd_soundfont *sf, struct snd_sf_sample *sp);
     40static int load_map(struct snd_sf_list *sflist, const void __user *data, int count);
     41static int load_info(struct snd_sf_list *sflist, const void __user *data, long count);
     42static int remove_info(struct snd_sf_list *sflist, struct snd_soundfont *sf,
     43		       int bank, int instr);
     44static void init_voice_info(struct soundfont_voice_info *avp);
     45static void init_voice_parm(struct soundfont_voice_parm *pp);
     46static struct snd_sf_sample *set_sample(struct snd_soundfont *sf,
     47					struct soundfont_voice_info *avp);
     48static struct snd_sf_sample *find_sample(struct snd_soundfont *sf, int sample_id);
     49static int load_data(struct snd_sf_list *sflist, const void __user *data, long count);
     50static void rebuild_presets(struct snd_sf_list *sflist);
     51static void add_preset(struct snd_sf_list *sflist, struct snd_sf_zone *cur);
     52static void delete_preset(struct snd_sf_list *sflist, struct snd_sf_zone *zp);
     53static struct snd_sf_zone *search_first_zone(struct snd_sf_list *sflist,
     54					     int bank, int preset, int key);
     55static int search_zones(struct snd_sf_list *sflist, int *notep, int vel,
     56			int preset, int bank, struct snd_sf_zone **table,
     57			int max_layers, int level);
     58static int get_index(int bank, int instr, int key);
     59static void snd_sf_init(struct snd_sf_list *sflist);
     60static void snd_sf_clear(struct snd_sf_list *sflist);
     61
     62/*
     63 * lock access to sflist
     64 */
     65static void
     66lock_preset(struct snd_sf_list *sflist)
     67{
     68	unsigned long flags;
     69	mutex_lock(&sflist->presets_mutex);
     70	spin_lock_irqsave(&sflist->lock, flags);
     71	sflist->presets_locked = 1;
     72	spin_unlock_irqrestore(&sflist->lock, flags);
     73}
     74
     75
     76/*
     77 * remove lock
     78 */
     79static void
     80unlock_preset(struct snd_sf_list *sflist)
     81{
     82	unsigned long flags;
     83	spin_lock_irqsave(&sflist->lock, flags);
     84	sflist->presets_locked = 0;
     85	spin_unlock_irqrestore(&sflist->lock, flags);
     86	mutex_unlock(&sflist->presets_mutex);
     87}
     88
     89
     90/*
     91 * close the patch if the patch was opened by this client.
     92 */
     93int
     94snd_soundfont_close_check(struct snd_sf_list *sflist, int client)
     95{
     96	unsigned long flags;
     97	spin_lock_irqsave(&sflist->lock, flags);
     98	if (sflist->open_client == client)  {
     99		spin_unlock_irqrestore(&sflist->lock, flags);
    100		return close_patch(sflist);
    101	}
    102	spin_unlock_irqrestore(&sflist->lock, flags);
    103	return 0;
    104}
    105
    106
    107/*
    108 * Deal with a soundfont patch.  Any driver could use these routines
    109 * although it was designed for the AWE64.
    110 *
    111 * The sample_write and callargs parameters allow a callback into
    112 * the actual driver to write sample data to the board or whatever
    113 * it wants to do with it.
    114 */
    115int
    116snd_soundfont_load(struct snd_sf_list *sflist, const void __user *data,
    117		   long count, int client)
    118{
    119	struct soundfont_patch_info patch;
    120	unsigned long flags;
    121	int  rc;
    122
    123	if (count < (long)sizeof(patch)) {
    124		snd_printk(KERN_ERR "patch record too small %ld\n", count);
    125		return -EINVAL;
    126	}
    127	if (copy_from_user(&patch, data, sizeof(patch)))
    128		return -EFAULT;
    129
    130	count -= sizeof(patch);
    131	data += sizeof(patch);
    132
    133	if (patch.key != SNDRV_OSS_SOUNDFONT_PATCH) {
    134		snd_printk(KERN_ERR "The wrong kind of patch %x\n", patch.key);
    135		return -EINVAL;
    136	}
    137	if (count < patch.len) {
    138		snd_printk(KERN_ERR "Patch too short %ld, need %d\n",
    139			   count, patch.len);
    140		return -EINVAL;
    141	}
    142	if (patch.len < 0) {
    143		snd_printk(KERN_ERR "poor length %d\n", patch.len);
    144		return -EINVAL;
    145	}
    146
    147	if (patch.type == SNDRV_SFNT_OPEN_PATCH) {
    148		/* grab sflist to open */
    149		lock_preset(sflist);
    150		rc = open_patch(sflist, data, count, client);
    151		unlock_preset(sflist);
    152		return rc;
    153	}
    154
    155	/* check if other client already opened patch */
    156	spin_lock_irqsave(&sflist->lock, flags);
    157	if (sflist->open_client != client) {
    158		spin_unlock_irqrestore(&sflist->lock, flags);
    159		return -EBUSY;
    160	}
    161	spin_unlock_irqrestore(&sflist->lock, flags);
    162
    163	lock_preset(sflist);
    164	rc = -EINVAL;
    165	switch (patch.type) {
    166	case SNDRV_SFNT_LOAD_INFO:
    167		rc = load_info(sflist, data, count);
    168		break;
    169	case SNDRV_SFNT_LOAD_DATA:
    170		rc = load_data(sflist, data, count);
    171		break;
    172	case SNDRV_SFNT_CLOSE_PATCH:
    173		rc = close_patch(sflist);
    174		break;
    175	case SNDRV_SFNT_REPLACE_DATA:
    176		/*rc = replace_data(&patch, data, count);*/
    177		break;
    178	case SNDRV_SFNT_MAP_PRESET:
    179		rc = load_map(sflist, data, count);
    180		break;
    181	case SNDRV_SFNT_PROBE_DATA:
    182		rc = probe_data(sflist, patch.optarg);
    183		break;
    184	case SNDRV_SFNT_REMOVE_INFO:
    185		/* patch must be opened */
    186		if (!sflist->currsf) {
    187			snd_printk(KERN_ERR "soundfont: remove_info: "
    188				   "patch not opened\n");
    189			rc = -EINVAL;
    190		} else {
    191			int bank, instr;
    192			bank = ((unsigned short)patch.optarg >> 8) & 0xff;
    193			instr = (unsigned short)patch.optarg & 0xff;
    194			if (! remove_info(sflist, sflist->currsf, bank, instr))
    195				rc = -EINVAL;
    196			else
    197				rc = 0;
    198		}
    199		break;
    200	}
    201	unlock_preset(sflist);
    202
    203	return rc;
    204}
    205
    206
    207/* check if specified type is special font (GUS or preset-alias) */
    208static inline int
    209is_special_type(int type)
    210{
    211	type &= 0x0f;
    212	return (type == SNDRV_SFNT_PAT_TYPE_GUS ||
    213		type == SNDRV_SFNT_PAT_TYPE_MAP);
    214}
    215
    216
    217/* open patch; create sf list */
    218static int
    219open_patch(struct snd_sf_list *sflist, const char __user *data,
    220	   int count, int client)
    221{
    222	struct soundfont_open_parm parm;
    223	struct snd_soundfont *sf;
    224	unsigned long flags;
    225
    226	spin_lock_irqsave(&sflist->lock, flags);
    227	if (sflist->open_client >= 0 || sflist->currsf) {
    228		spin_unlock_irqrestore(&sflist->lock, flags);
    229		return -EBUSY;
    230	}
    231	spin_unlock_irqrestore(&sflist->lock, flags);
    232
    233	if (copy_from_user(&parm, data, sizeof(parm)))
    234		return -EFAULT;
    235
    236	if (is_special_type(parm.type)) {
    237		parm.type |= SNDRV_SFNT_PAT_SHARED;
    238		sf = newsf(sflist, parm.type, NULL);
    239	} else 
    240		sf = newsf(sflist, parm.type, parm.name);
    241	if (sf == NULL) {
    242		return -ENOMEM;
    243	}
    244
    245	spin_lock_irqsave(&sflist->lock, flags);
    246	sflist->open_client = client;
    247	sflist->currsf = sf;
    248	spin_unlock_irqrestore(&sflist->lock, flags);
    249
    250	return 0;
    251}
    252
    253/*
    254 * Allocate a new soundfont structure.
    255 */
    256static struct snd_soundfont *
    257newsf(struct snd_sf_list *sflist, int type, char *name)
    258{
    259	struct snd_soundfont *sf;
    260
    261	/* check the shared fonts */
    262	if (type & SNDRV_SFNT_PAT_SHARED) {
    263		for (sf = sflist->fonts; sf; sf = sf->next) {
    264			if (is_identical_font(sf, type, name)) {
    265				return sf;
    266			}
    267		}
    268	}
    269
    270	/* not found -- create a new one */
    271	sf = kzalloc(sizeof(*sf), GFP_KERNEL);
    272	if (sf == NULL)
    273		return NULL;
    274	sf->id = sflist->fonts_size;
    275	sflist->fonts_size++;
    276
    277	/* prepend this record */
    278	sf->next = sflist->fonts;
    279	sflist->fonts = sf;
    280
    281	sf->type = type;
    282	sf->zones = NULL;
    283	sf->samples = NULL;
    284	if (name)
    285		memcpy(sf->name, name, SNDRV_SFNT_PATCH_NAME_LEN);
    286
    287	return sf;
    288}
    289
    290/* check if the given name matches to the existing list */
    291static int
    292is_identical_font(struct snd_soundfont *sf, int type, unsigned char *name)
    293{
    294	return ((sf->type & SNDRV_SFNT_PAT_SHARED) &&
    295		(sf->type & 0x0f) == (type & 0x0f) &&
    296		(name == NULL ||
    297		 memcmp(sf->name, name, SNDRV_SFNT_PATCH_NAME_LEN) == 0));
    298}
    299
    300/*
    301 * Close the current patch.
    302 */
    303static int
    304close_patch(struct snd_sf_list *sflist)
    305{
    306	unsigned long flags;
    307
    308	spin_lock_irqsave(&sflist->lock, flags);
    309	sflist->currsf = NULL;
    310	sflist->open_client = -1;
    311	spin_unlock_irqrestore(&sflist->lock, flags);
    312
    313	rebuild_presets(sflist);
    314
    315	return 0;
    316
    317}
    318
    319/* probe sample in the current list -- nothing to be loaded */
    320static int
    321probe_data(struct snd_sf_list *sflist, int sample_id)
    322{
    323	/* patch must be opened */
    324	if (sflist->currsf) {
    325		/* search the specified sample by optarg */
    326		if (find_sample(sflist->currsf, sample_id))
    327			return 0;
    328	}
    329	return -EINVAL;
    330}
    331
    332/*
    333 * increment zone counter
    334 */
    335static void
    336set_zone_counter(struct snd_sf_list *sflist, struct snd_soundfont *sf,
    337		 struct snd_sf_zone *zp)
    338{
    339	zp->counter = sflist->zone_counter++;
    340	if (sf->type & SNDRV_SFNT_PAT_LOCKED)
    341		sflist->zone_locked = sflist->zone_counter;
    342}
    343
    344/*
    345 * allocate a new zone record
    346 */
    347static struct snd_sf_zone *
    348sf_zone_new(struct snd_sf_list *sflist, struct snd_soundfont *sf)
    349{
    350	struct snd_sf_zone *zp;
    351
    352	zp = kzalloc(sizeof(*zp), GFP_KERNEL);
    353	if (!zp)
    354		return NULL;
    355	zp->next = sf->zones;
    356	sf->zones = zp;
    357
    358	init_voice_info(&zp->v);
    359
    360	set_zone_counter(sflist, sf, zp);
    361	return zp;
    362}
    363
    364
    365/*
    366 * increment sample counter
    367 */
    368static void
    369set_sample_counter(struct snd_sf_list *sflist, struct snd_soundfont *sf,
    370		   struct snd_sf_sample *sp)
    371{
    372	sp->counter = sflist->sample_counter++;
    373	if (sf->type & SNDRV_SFNT_PAT_LOCKED)
    374		sflist->sample_locked = sflist->sample_counter;
    375}
    376
    377/*
    378 * allocate a new sample list record
    379 */
    380static struct snd_sf_sample *
    381sf_sample_new(struct snd_sf_list *sflist, struct snd_soundfont *sf)
    382{
    383	struct snd_sf_sample *sp;
    384
    385	sp = kzalloc(sizeof(*sp), GFP_KERNEL);
    386	if (!sp)
    387		return NULL;
    388
    389	sp->next = sf->samples;
    390	sf->samples = sp;
    391
    392	set_sample_counter(sflist, sf, sp);
    393	return sp;
    394}
    395
    396/*
    397 * delete sample list -- this is an exceptional job.
    398 * only the last allocated sample can be deleted.
    399 */
    400static void
    401sf_sample_delete(struct snd_sf_list *sflist, struct snd_soundfont *sf,
    402		 struct snd_sf_sample *sp)
    403{
    404	/* only last sample is accepted */
    405	if (sp == sf->samples) {
    406		sf->samples = sp->next;
    407		kfree(sp);
    408	}
    409}
    410
    411
    412/* load voice map */
    413static int
    414load_map(struct snd_sf_list *sflist, const void __user *data, int count)
    415{
    416	struct snd_sf_zone *zp, *prevp;
    417	struct snd_soundfont *sf;
    418	struct soundfont_voice_map map;
    419
    420	/* get the link info */
    421	if (count < (int)sizeof(map))
    422		return -EINVAL;
    423	if (copy_from_user(&map, data, sizeof(map)))
    424		return -EFAULT;
    425
    426	if (map.map_instr < 0 || map.map_instr >= SF_MAX_INSTRUMENTS)
    427		return -EINVAL;
    428	
    429	sf = newsf(sflist, SNDRV_SFNT_PAT_TYPE_MAP|SNDRV_SFNT_PAT_SHARED, NULL);
    430	if (sf == NULL)
    431		return -ENOMEM;
    432
    433	prevp = NULL;
    434	for (zp = sf->zones; zp; prevp = zp, zp = zp->next) {
    435		if (zp->mapped &&
    436		    zp->instr == map.map_instr &&
    437		    zp->bank == map.map_bank &&
    438		    zp->v.low == map.map_key &&
    439		    zp->v.start == map.src_instr &&
    440		    zp->v.end == map.src_bank &&
    441		    zp->v.fixkey == map.src_key) {
    442			/* the same mapping is already present */
    443			/* relink this record to the link head */
    444			if (prevp) {
    445				prevp->next = zp->next;
    446				zp->next = sf->zones;
    447				sf->zones = zp;
    448			}
    449			/* update the counter */
    450			set_zone_counter(sflist, sf, zp);
    451			return 0;
    452		}
    453	}
    454
    455	/* create a new zone */
    456	zp = sf_zone_new(sflist, sf);
    457	if (!zp)
    458		return -ENOMEM;
    459
    460	zp->bank = map.map_bank;
    461	zp->instr = map.map_instr;
    462	zp->mapped = 1;
    463	if (map.map_key >= 0) {
    464		zp->v.low = map.map_key;
    465		zp->v.high = map.map_key;
    466	}
    467	zp->v.start = map.src_instr;
    468	zp->v.end = map.src_bank;
    469	zp->v.fixkey = map.src_key;
    470	zp->v.sf_id = sf->id;
    471
    472	add_preset(sflist, zp);
    473
    474	return 0;
    475}
    476
    477
    478/* remove the present instrument layers */
    479static int
    480remove_info(struct snd_sf_list *sflist, struct snd_soundfont *sf,
    481	    int bank, int instr)
    482{
    483	struct snd_sf_zone *prev, *next, *p;
    484	int removed = 0;
    485
    486	prev = NULL;
    487	for (p = sf->zones; p; p = next) {
    488		next = p->next;
    489		if (! p->mapped &&
    490		    p->bank == bank && p->instr == instr) {
    491			/* remove this layer */
    492			if (prev)
    493				prev->next = next;
    494			else
    495				sf->zones = next;
    496			removed++;
    497			kfree(p);
    498		} else
    499			prev = p;
    500	}
    501	if (removed)
    502		rebuild_presets(sflist);
    503	return removed;
    504}
    505
    506
    507/*
    508 * Read an info record from the user buffer and save it on the current
    509 * open soundfont.
    510 */
    511static int
    512load_info(struct snd_sf_list *sflist, const void __user *data, long count)
    513{
    514	struct snd_soundfont *sf;
    515	struct snd_sf_zone *zone;
    516	struct soundfont_voice_rec_hdr hdr;
    517	int i;
    518
    519	/* patch must be opened */
    520	sf = sflist->currsf;
    521	if (!sf)
    522		return -EINVAL;
    523
    524	if (is_special_type(sf->type))
    525		return -EINVAL;
    526
    527	if (count < (long)sizeof(hdr)) {
    528		printk(KERN_ERR "Soundfont error: invalid patch zone length\n");
    529		return -EINVAL;
    530	}
    531	if (copy_from_user((char*)&hdr, data, sizeof(hdr)))
    532		return -EFAULT;
    533	
    534	data += sizeof(hdr);
    535	count -= sizeof(hdr);
    536
    537	if (hdr.nvoices <= 0 || hdr.nvoices >= 100) {
    538		printk(KERN_ERR "Soundfont error: Illegal voice number %d\n",
    539		       hdr.nvoices);
    540		return -EINVAL;
    541	}
    542
    543	if (count < (long)sizeof(struct soundfont_voice_info) * hdr.nvoices) {
    544		printk(KERN_ERR "Soundfont Error: "
    545		       "patch length(%ld) is smaller than nvoices(%d)\n",
    546		       count, hdr.nvoices);
    547		return -EINVAL;
    548	}
    549
    550	switch (hdr.write_mode) {
    551	case SNDRV_SFNT_WR_EXCLUSIVE:
    552		/* exclusive mode - if the instrument already exists,
    553		   return error */
    554		for (zone = sf->zones; zone; zone = zone->next) {
    555			if (!zone->mapped &&
    556			    zone->bank == hdr.bank &&
    557			    zone->instr == hdr.instr)
    558				return -EINVAL;
    559		}
    560		break;
    561	case SNDRV_SFNT_WR_REPLACE:
    562		/* replace mode - remove the instrument if it already exists */
    563		remove_info(sflist, sf, hdr.bank, hdr.instr);
    564		break;
    565	}
    566
    567	for (i = 0; i < hdr.nvoices; i++) {
    568		struct snd_sf_zone tmpzone;
    569
    570		/* copy awe_voice_info parameters */
    571		if (copy_from_user(&tmpzone.v, data, sizeof(tmpzone.v))) {
    572			return -EFAULT;
    573		}
    574
    575		data += sizeof(tmpzone.v);
    576		count -= sizeof(tmpzone.v);
    577
    578		tmpzone.bank = hdr.bank;
    579		tmpzone.instr = hdr.instr;
    580		tmpzone.mapped = 0;
    581		tmpzone.v.sf_id = sf->id;
    582		if (tmpzone.v.mode & SNDRV_SFNT_MODE_INIT_PARM)
    583			init_voice_parm(&tmpzone.v.parm);
    584
    585		/* create a new zone */
    586		zone = sf_zone_new(sflist, sf);
    587		if (!zone)
    588			return -ENOMEM;
    589
    590		/* copy the temporary data */
    591		zone->bank = tmpzone.bank;
    592		zone->instr = tmpzone.instr;
    593		zone->v = tmpzone.v;
    594
    595		/* look up the sample */
    596		zone->sample = set_sample(sf, &zone->v);
    597	}
    598
    599	return 0;
    600}
    601
    602
    603/* initialize voice_info record */
    604static void
    605init_voice_info(struct soundfont_voice_info *avp)
    606{
    607	memset(avp, 0, sizeof(*avp));
    608
    609	avp->root = 60;
    610	avp->high = 127;
    611	avp->velhigh = 127;
    612	avp->fixkey = -1;
    613	avp->fixvel = -1;
    614	avp->fixpan = -1;
    615	avp->pan = -1;
    616	avp->amplitude = 127;
    617	avp->scaleTuning = 100;
    618
    619	init_voice_parm(&avp->parm);
    620}
    621
    622/* initialize voice_parm record:
    623 * Env1/2: delay=0, attack=0, hold=0, sustain=0, decay=0, release=0.
    624 * Vibrato and Tremolo effects are zero.
    625 * Cutoff is maximum.
    626 * Chorus and Reverb effects are zero.
    627 */
    628static void
    629init_voice_parm(struct soundfont_voice_parm *pp)
    630{
    631	memset(pp, 0, sizeof(*pp));
    632
    633	pp->moddelay = 0x8000;
    634	pp->modatkhld = 0x7f7f;
    635	pp->moddcysus = 0x7f7f;
    636	pp->modrelease = 0x807f;
    637
    638	pp->voldelay = 0x8000;
    639	pp->volatkhld = 0x7f7f;
    640	pp->voldcysus = 0x7f7f;
    641	pp->volrelease = 0x807f;
    642
    643	pp->lfo1delay = 0x8000;
    644	pp->lfo2delay = 0x8000;
    645
    646	pp->cutoff = 0xff;
    647}	
    648
    649/* search the specified sample */
    650static struct snd_sf_sample *
    651set_sample(struct snd_soundfont *sf, struct soundfont_voice_info *avp)
    652{
    653	struct snd_sf_sample *sample;
    654
    655	sample = find_sample(sf, avp->sample);
    656	if (sample == NULL)
    657		return NULL;
    658
    659	/* add in the actual sample offsets:
    660	 * The voice_info addresses define only the relative offset
    661	 * from sample pointers.  Here we calculate the actual DRAM
    662	 * offset from sample pointers.
    663	 */
    664	avp->start += sample->v.start;
    665	avp->end += sample->v.end;
    666	avp->loopstart += sample->v.loopstart;
    667	avp->loopend += sample->v.loopend;
    668
    669	/* copy mode flags */
    670	avp->sample_mode = sample->v.mode_flags;
    671
    672	return sample;
    673}
    674
    675/* find the sample pointer with the given id in the soundfont */
    676static struct snd_sf_sample *
    677find_sample(struct snd_soundfont *sf, int sample_id)
    678{
    679	struct snd_sf_sample *p;
    680
    681	if (sf == NULL)
    682		return NULL;
    683
    684	for (p = sf->samples; p; p = p->next) {
    685		if (p->v.sample == sample_id)
    686			return p;
    687	}
    688	return NULL;
    689}
    690
    691
    692/*
    693 * Load sample information, this can include data to be loaded onto
    694 * the soundcard.  It can also just be a pointer into soundcard ROM.
    695 * If there is data it will be written to the soundcard via the callback
    696 * routine.
    697 */
    698static int
    699load_data(struct snd_sf_list *sflist, const void __user *data, long count)
    700{
    701	struct snd_soundfont *sf;
    702	struct soundfont_sample_info sample_info;
    703	struct snd_sf_sample *sp;
    704	long off;
    705
    706	/* patch must be opened */
    707	sf = sflist->currsf;
    708	if (!sf)
    709		return -EINVAL;
    710
    711	if (is_special_type(sf->type))
    712		return -EINVAL;
    713
    714	if (copy_from_user(&sample_info, data, sizeof(sample_info)))
    715		return -EFAULT;
    716
    717	off = sizeof(sample_info);
    718
    719	if (sample_info.size != (count-off)/2)
    720		return -EINVAL;
    721
    722	/* Check for dup */
    723	if (find_sample(sf, sample_info.sample)) {
    724		/* if shared sample, skip this data */
    725		if (sf->type & SNDRV_SFNT_PAT_SHARED)
    726			return 0;
    727		return -EINVAL;
    728	}
    729
    730	/* Allocate a new sample structure */
    731	sp = sf_sample_new(sflist, sf);
    732	if (!sp)
    733		return -ENOMEM;
    734
    735	sp->v = sample_info;
    736	sp->v.sf_id = sf->id;
    737	sp->v.dummy = 0;
    738	sp->v.truesize = sp->v.size;
    739
    740	/*
    741	 * If there is wave data then load it.
    742	 */
    743	if (sp->v.size > 0) {
    744		int  rc;
    745		rc = sflist->callback.sample_new
    746			(sflist->callback.private_data, sp, sflist->memhdr,
    747			 data + off, count - off);
    748		if (rc < 0) {
    749			sf_sample_delete(sflist, sf, sp);
    750			return rc;
    751		}
    752		sflist->mem_used += sp->v.truesize;
    753	}
    754
    755	return count;
    756}
    757
    758
    759/* log2_tbl[i] = log2(i+128) * 0x10000 */
    760static const int log_tbl[129] = {
    761	0x70000, 0x702df, 0x705b9, 0x7088e, 0x70b5d, 0x70e26, 0x710eb, 0x713aa,
    762	0x71663, 0x71918, 0x71bc8, 0x71e72, 0x72118, 0x723b9, 0x72655, 0x728ed,
    763	0x72b80, 0x72e0e, 0x73098, 0x7331d, 0x7359e, 0x7381b, 0x73a93, 0x73d08,
    764	0x73f78, 0x741e4, 0x7444c, 0x746b0, 0x74910, 0x74b6c, 0x74dc4, 0x75019,
    765	0x75269, 0x754b6, 0x75700, 0x75946, 0x75b88, 0x75dc7, 0x76002, 0x7623a,
    766	0x7646e, 0x766a0, 0x768cd, 0x76af8, 0x76d1f, 0x76f43, 0x77164, 0x77382,
    767	0x7759d, 0x777b4, 0x779c9, 0x77bdb, 0x77dea, 0x77ff5, 0x781fe, 0x78404,
    768	0x78608, 0x78808, 0x78a06, 0x78c01, 0x78df9, 0x78fef, 0x791e2, 0x793d2,
    769	0x795c0, 0x797ab, 0x79993, 0x79b79, 0x79d5d, 0x79f3e, 0x7a11d, 0x7a2f9,
    770	0x7a4d3, 0x7a6ab, 0x7a880, 0x7aa53, 0x7ac24, 0x7adf2, 0x7afbe, 0x7b188,
    771	0x7b350, 0x7b515, 0x7b6d8, 0x7b899, 0x7ba58, 0x7bc15, 0x7bdd0, 0x7bf89,
    772	0x7c140, 0x7c2f5, 0x7c4a7, 0x7c658, 0x7c807, 0x7c9b3, 0x7cb5e, 0x7cd07,
    773	0x7ceae, 0x7d053, 0x7d1f7, 0x7d398, 0x7d538, 0x7d6d6, 0x7d872, 0x7da0c,
    774	0x7dba4, 0x7dd3b, 0x7ded0, 0x7e063, 0x7e1f4, 0x7e384, 0x7e512, 0x7e69f,
    775	0x7e829, 0x7e9b3, 0x7eb3a, 0x7ecc0, 0x7ee44, 0x7efc7, 0x7f148, 0x7f2c8,
    776	0x7f446, 0x7f5c2, 0x7f73d, 0x7f8b7, 0x7fa2f, 0x7fba5, 0x7fd1a, 0x7fe8d,
    777	0x80000,
    778};
    779
    780/* convert from linear to log value
    781 *
    782 * conversion: value = log2(amount / base) * ratio
    783 *
    784 * argument:
    785 *   amount = linear value (unsigned, 32bit max)
    786 *   offset = base offset (:= log2(base) * 0x10000)
    787 *   ratio = division ratio
    788 *
    789 */
    790int
    791snd_sf_linear_to_log(unsigned int amount, int offset, int ratio)
    792{
    793	int v;
    794	int s, low, bit;
    795	
    796	if (amount < 2)
    797		return 0;
    798	for (bit = 0; ! (amount & 0x80000000L); bit++)
    799		amount <<= 1;
    800	s = (amount >> 24) & 0x7f;
    801	low = (amount >> 16) & 0xff;
    802	/* linear approximation by lower 8 bit */
    803	v = (log_tbl[s + 1] * low + log_tbl[s] * (0x100 - low)) >> 8;
    804	v -= offset;
    805	v = (v * ratio) >> 16;
    806	v += (24 - bit) * ratio;
    807	return v;
    808}
    809
    810EXPORT_SYMBOL(snd_sf_linear_to_log);
    811
    812
    813#define OFFSET_MSEC		653117		/* base = 1000 */
    814#define OFFSET_ABSCENT		851781		/* base = 8176 */
    815#define OFFSET_SAMPLERATE	1011119		/* base = 44100 */
    816
    817#define ABSCENT_RATIO		1200
    818#define TIMECENT_RATIO		1200
    819#define SAMPLERATE_RATIO	4096
    820
    821/*
    822 * mHz to abscent
    823 * conversion: abscent = log2(MHz / 8176) * 1200
    824 */
    825static int
    826freq_to_note(int mhz)
    827{
    828	return snd_sf_linear_to_log(mhz, OFFSET_ABSCENT, ABSCENT_RATIO);
    829}
    830
    831/* convert Hz to AWE32 rate offset:
    832 * sample pitch offset for the specified sample rate
    833 * rate=44100 is no offset, each 4096 is 1 octave (twice).
    834 * eg, when rate is 22050, this offset becomes -4096.
    835 *
    836 * conversion: offset = log2(Hz / 44100) * 4096
    837 */
    838static int
    839calc_rate_offset(int hz)
    840{
    841	return snd_sf_linear_to_log(hz, OFFSET_SAMPLERATE, SAMPLERATE_RATIO);
    842}
    843
    844
    845/* calculate GUS envelope time */
    846static int
    847calc_gus_envelope_time(int rate, int start, int end)
    848{
    849	int r, p, t;
    850	r = (3 - ((rate >> 6) & 3)) * 3;
    851	p = rate & 0x3f;
    852	if (!p)
    853		p = 1;
    854	t = end - start;
    855	if (t < 0) t = -t;
    856	if (13 > r)
    857		t = t << (13 - r);
    858	else
    859		t = t >> (r - 13);
    860	return (t * 10) / (p * 441);
    861}
    862
    863/* convert envelope time parameter to soundfont parameters */
    864
    865/* attack & decay/release time table (msec) */
    866static const short attack_time_tbl[128] = {
    86732767, 32767, 5989, 4235, 2994, 2518, 2117, 1780, 1497, 1373, 1259, 1154, 1058, 970, 890, 816,
    868707, 691, 662, 634, 607, 581, 557, 533, 510, 489, 468, 448, 429, 411, 393, 377,
    869361, 345, 331, 317, 303, 290, 278, 266, 255, 244, 234, 224, 214, 205, 196, 188,
    870180, 172, 165, 158, 151, 145, 139, 133, 127, 122, 117, 112, 107, 102, 98, 94,
    87190, 86, 82, 79, 75, 72, 69, 66, 63, 61, 58, 56, 53, 51, 49, 47,
    87245, 43, 41, 39, 37, 36, 34, 33, 31, 30, 29, 28, 26, 25, 24, 23,
    87322, 21, 20, 19, 19, 18, 17, 16, 16, 15, 15, 14, 13, 13, 12, 12,
    87411, 11, 10, 10, 10, 9, 9, 8, 8, 8, 8, 7, 7, 7, 6, 0,
    875};
    876
    877static const short decay_time_tbl[128] = {
    87832767, 32767, 22614, 15990, 11307, 9508, 7995, 6723, 5653, 5184, 4754, 4359, 3997, 3665, 3361, 3082,
    8792828, 2765, 2648, 2535, 2428, 2325, 2226, 2132, 2042, 1955, 1872, 1793, 1717, 1644, 1574, 1507,
    8801443, 1382, 1324, 1267, 1214, 1162, 1113, 1066, 978, 936, 897, 859, 822, 787, 754, 722,
    881691, 662, 634, 607, 581, 557, 533, 510, 489, 468, 448, 429, 411, 393, 377, 361,
    882345, 331, 317, 303, 290, 278, 266, 255, 244, 234, 224, 214, 205, 196, 188, 180,
    883172, 165, 158, 151, 145, 139, 133, 127, 122, 117, 112, 107, 102, 98, 94, 90,
    88486, 82, 79, 75, 72, 69, 66, 63, 61, 58, 56, 53, 51, 49, 47, 45,
    88543, 41, 39, 37, 36, 34, 33, 31, 30, 29, 28, 26, 25, 24, 23, 22,
    886};
    887
    888/* delay time = 0x8000 - msec/92 */
    889int
    890snd_sf_calc_parm_hold(int msec)
    891{
    892	int val = (0x7f * 92 - msec) / 92;
    893	if (val < 1) val = 1;
    894	if (val >= 126) val = 126;
    895	return val;
    896}
    897
    898/* search an index for specified time from given time table */
    899static int
    900calc_parm_search(int msec, const short *table)
    901{
    902	int left = 1, right = 127, mid;
    903	while (left < right) {
    904		mid = (left + right) / 2;
    905		if (msec < (int)table[mid])
    906			left = mid + 1;
    907		else
    908			right = mid;
    909	}
    910	return left;
    911}
    912
    913/* attack time: search from time table */
    914int
    915snd_sf_calc_parm_attack(int msec)
    916{
    917	return calc_parm_search(msec, attack_time_tbl);
    918}
    919
    920/* decay/release time: search from time table */
    921int
    922snd_sf_calc_parm_decay(int msec)
    923{
    924	return calc_parm_search(msec, decay_time_tbl);
    925}
    926
    927int snd_sf_vol_table[128] = {
    928	255,111,95,86,79,74,70,66,63,61,58,56,54,52,50,49,
    929	47,46,45,43,42,41,40,39,38,37,36,35,34,34,33,32,
    930	31,31,30,29,29,28,27,27,26,26,25,24,24,23,23,22,
    931	22,21,21,21,20,20,19,19,18,18,18,17,17,16,16,16,
    932	15,15,15,14,14,14,13,13,13,12,12,12,11,11,11,10,
    933	10,10,10,9,9,9,8,8,8,8,7,7,7,7,6,6,
    934	6,6,5,5,5,5,5,4,4,4,4,3,3,3,3,3,
    935	2,2,2,2,2,1,1,1,1,1,0,0,0,0,0,0,
    936};
    937
    938
    939#define calc_gus_sustain(val)  (0x7f - snd_sf_vol_table[(val)/2])
    940#define calc_gus_attenuation(val)	snd_sf_vol_table[(val)/2]
    941
    942/* load GUS patch */
    943static int
    944load_guspatch(struct snd_sf_list *sflist, const char __user *data,
    945	      long count, int client)
    946{
    947	struct patch_info patch;
    948	struct snd_soundfont *sf;
    949	struct snd_sf_zone *zone;
    950	struct snd_sf_sample *smp;
    951	int note, sample_id;
    952	int rc;
    953
    954	if (count < (long)sizeof(patch)) {
    955		snd_printk(KERN_ERR "patch record too small %ld\n", count);
    956		return -EINVAL;
    957	}
    958	if (copy_from_user(&patch, data, sizeof(patch)))
    959		return -EFAULT;
    960	
    961	count -= sizeof(patch);
    962	data += sizeof(patch);
    963
    964	sf = newsf(sflist, SNDRV_SFNT_PAT_TYPE_GUS|SNDRV_SFNT_PAT_SHARED, NULL);
    965	if (sf == NULL)
    966		return -ENOMEM;
    967	smp = sf_sample_new(sflist, sf);
    968	if (!smp)
    969		return -ENOMEM;
    970	sample_id = sflist->sample_counter;
    971	smp->v.sample = sample_id;
    972	smp->v.start = 0;
    973	smp->v.end = patch.len;
    974	smp->v.loopstart = patch.loop_start;
    975	smp->v.loopend = patch.loop_end;
    976	smp->v.size = patch.len;
    977
    978	/* set up mode flags */
    979	smp->v.mode_flags = 0;
    980	if (!(patch.mode & WAVE_16_BITS))
    981		smp->v.mode_flags |= SNDRV_SFNT_SAMPLE_8BITS;
    982	if (patch.mode & WAVE_UNSIGNED)
    983		smp->v.mode_flags |= SNDRV_SFNT_SAMPLE_UNSIGNED;
    984	smp->v.mode_flags |= SNDRV_SFNT_SAMPLE_NO_BLANK;
    985	if (!(patch.mode & (WAVE_LOOPING|WAVE_BIDIR_LOOP|WAVE_LOOP_BACK)))
    986		smp->v.mode_flags |= SNDRV_SFNT_SAMPLE_SINGLESHOT;
    987	if (patch.mode & WAVE_BIDIR_LOOP)
    988		smp->v.mode_flags |= SNDRV_SFNT_SAMPLE_BIDIR_LOOP;
    989	if (patch.mode & WAVE_LOOP_BACK)
    990		smp->v.mode_flags |= SNDRV_SFNT_SAMPLE_REVERSE_LOOP;
    991
    992	if (patch.mode & WAVE_16_BITS) {
    993		/* convert to word offsets */
    994		smp->v.size /= 2;
    995		smp->v.end /= 2;
    996		smp->v.loopstart /= 2;
    997		smp->v.loopend /= 2;
    998	}
    999	/*smp->v.loopend++;*/
   1000
   1001	smp->v.dummy = 0;
   1002	smp->v.truesize = 0;
   1003	smp->v.sf_id = sf->id;
   1004
   1005	/* set up voice info */
   1006	zone = sf_zone_new(sflist, sf);
   1007	if (!zone) {
   1008		sf_sample_delete(sflist, sf, smp);
   1009		return -ENOMEM;
   1010	}
   1011
   1012	/*
   1013	 * load wave data
   1014	 */
   1015	if (sflist->callback.sample_new) {
   1016		rc = sflist->callback.sample_new
   1017			(sflist->callback.private_data, smp, sflist->memhdr,
   1018			 data, count);
   1019		if (rc < 0) {
   1020			sf_sample_delete(sflist, sf, smp);
   1021			kfree(zone);
   1022			return rc;
   1023		}
   1024		/* memory offset is updated after */
   1025	}
   1026
   1027	/* update the memory offset here */
   1028	sflist->mem_used += smp->v.truesize;
   1029
   1030	zone->v.sample = sample_id; /* the last sample */
   1031	zone->v.rate_offset = calc_rate_offset(patch.base_freq);
   1032	note = freq_to_note(patch.base_note);
   1033	zone->v.root = note / 100;
   1034	zone->v.tune = -(note % 100);
   1035	zone->v.low = (freq_to_note(patch.low_note) + 99) / 100;
   1036	zone->v.high = freq_to_note(patch.high_note) / 100;
   1037	/* panning position; -128 - 127 => 0-127 */
   1038	zone->v.pan = (patch.panning + 128) / 2;
   1039#if 0
   1040	snd_printk(KERN_DEBUG
   1041		   "gus: basefrq=%d (ofs=%d) root=%d,tune=%d, range:%d-%d\n",
   1042		   (int)patch.base_freq, zone->v.rate_offset,
   1043		   zone->v.root, zone->v.tune, zone->v.low, zone->v.high);
   1044#endif
   1045
   1046	/* detuning is ignored */
   1047	/* 6points volume envelope */
   1048	if (patch.mode & WAVE_ENVELOPES) {
   1049		int attack, hold, decay, release;
   1050		attack = calc_gus_envelope_time
   1051			(patch.env_rate[0], 0, patch.env_offset[0]);
   1052		hold = calc_gus_envelope_time
   1053			(patch.env_rate[1], patch.env_offset[0],
   1054			 patch.env_offset[1]);
   1055		decay = calc_gus_envelope_time
   1056			(patch.env_rate[2], patch.env_offset[1],
   1057			 patch.env_offset[2]);
   1058		release = calc_gus_envelope_time
   1059			(patch.env_rate[3], patch.env_offset[1],
   1060			 patch.env_offset[4]);
   1061		release += calc_gus_envelope_time
   1062			(patch.env_rate[4], patch.env_offset[3],
   1063			 patch.env_offset[4]);
   1064		release += calc_gus_envelope_time
   1065			(patch.env_rate[5], patch.env_offset[4],
   1066			 patch.env_offset[5]);
   1067		zone->v.parm.volatkhld = 
   1068			(snd_sf_calc_parm_hold(hold) << 8) |
   1069			snd_sf_calc_parm_attack(attack);
   1070		zone->v.parm.voldcysus = (calc_gus_sustain(patch.env_offset[2]) << 8) |
   1071			snd_sf_calc_parm_decay(decay);
   1072		zone->v.parm.volrelease = 0x8000 | snd_sf_calc_parm_decay(release);
   1073		zone->v.attenuation = calc_gus_attenuation(patch.env_offset[0]);
   1074#if 0
   1075		snd_printk(KERN_DEBUG
   1076			   "gus: atkhld=%x, dcysus=%x, volrel=%x, att=%d\n",
   1077			   zone->v.parm.volatkhld,
   1078			   zone->v.parm.voldcysus,
   1079			   zone->v.parm.volrelease,
   1080			   zone->v.attenuation);
   1081#endif
   1082	}
   1083
   1084	/* fast release */
   1085	if (patch.mode & WAVE_FAST_RELEASE) {
   1086		zone->v.parm.volrelease = 0x807f;
   1087	}
   1088
   1089	/* tremolo effect */
   1090	if (patch.mode & WAVE_TREMOLO) {
   1091		int rate = (patch.tremolo_rate * 1000 / 38) / 42;
   1092		zone->v.parm.tremfrq = ((patch.tremolo_depth / 2) << 8) | rate;
   1093	}
   1094	/* vibrato effect */
   1095	if (patch.mode & WAVE_VIBRATO) {
   1096		int rate = (patch.vibrato_rate * 1000 / 38) / 42;
   1097		zone->v.parm.fm2frq2 = ((patch.vibrato_depth / 6) << 8) | rate;
   1098	}
   1099	
   1100	/* scale_freq, scale_factor, volume, and fractions not implemented */
   1101
   1102	if (!(smp->v.mode_flags & SNDRV_SFNT_SAMPLE_SINGLESHOT))
   1103		zone->v.mode = SNDRV_SFNT_MODE_LOOPING;
   1104	else
   1105		zone->v.mode = 0;
   1106
   1107	/* append to the tail of the list */
   1108	/*zone->bank = ctrls[AWE_MD_GUS_BANK];*/
   1109	zone->bank = 0;
   1110	zone->instr = patch.instr_no;
   1111	zone->mapped = 0;
   1112	zone->v.sf_id = sf->id;
   1113
   1114	zone->sample = set_sample(sf, &zone->v);
   1115
   1116	/* rebuild preset now */
   1117	add_preset(sflist, zone);
   1118
   1119	return 0;
   1120}
   1121
   1122/* load GUS patch */
   1123int
   1124snd_soundfont_load_guspatch(struct snd_sf_list *sflist, const char __user *data,
   1125			    long count, int client)
   1126{
   1127	int rc;
   1128	lock_preset(sflist);
   1129	rc = load_guspatch(sflist, data, count, client);
   1130	unlock_preset(sflist);
   1131	return rc;
   1132}
   1133
   1134
   1135/*
   1136 * Rebuild the preset table.  This is like a hash table in that it allows
   1137 * quick access to the zone information.  For each preset there are zone
   1138 * structures linked by next_instr and by next_zone.  Former is the whole
   1139 * link for this preset, and latter is the link for zone (i.e. instrument/
   1140 * bank/key combination).
   1141 */
   1142static void
   1143rebuild_presets(struct snd_sf_list *sflist)
   1144{
   1145	struct snd_soundfont *sf;
   1146	struct snd_sf_zone *cur;
   1147
   1148	/* clear preset table */
   1149	memset(sflist->presets, 0, sizeof(sflist->presets));
   1150
   1151	/* search all fonts and insert each font */
   1152	for (sf = sflist->fonts; sf; sf = sf->next) {
   1153		for (cur = sf->zones; cur; cur = cur->next) {
   1154			if (! cur->mapped && cur->sample == NULL) {
   1155				/* try again to search the corresponding sample */
   1156				cur->sample = set_sample(sf, &cur->v);
   1157				if (cur->sample == NULL)
   1158					continue;
   1159			}
   1160
   1161			add_preset(sflist, cur);
   1162		}
   1163	}
   1164}
   1165
   1166
   1167/*
   1168 * add the given zone to preset table
   1169 */
   1170static void
   1171add_preset(struct snd_sf_list *sflist, struct snd_sf_zone *cur)
   1172{
   1173	struct snd_sf_zone *zone;
   1174	int index;
   1175
   1176	zone = search_first_zone(sflist, cur->bank, cur->instr, cur->v.low);
   1177	if (zone && zone->v.sf_id != cur->v.sf_id) {
   1178		/* different instrument was already defined */
   1179		struct snd_sf_zone *p;
   1180		/* compare the allocated time */
   1181		for (p = zone; p; p = p->next_zone) {
   1182			if (p->counter > cur->counter)
   1183				/* the current is older.. skipped */
   1184				return;
   1185		}
   1186		/* remove old zones */
   1187		delete_preset(sflist, zone);
   1188		zone = NULL; /* do not forget to clear this! */
   1189	}
   1190
   1191	/* prepend this zone */
   1192	index = get_index(cur->bank, cur->instr, cur->v.low);
   1193	if (index < 0)
   1194		return;
   1195	cur->next_zone = zone; /* zone link */
   1196	cur->next_instr = sflist->presets[index]; /* preset table link */
   1197	sflist->presets[index] = cur;
   1198}
   1199
   1200/*
   1201 * delete the given zones from preset_table
   1202 */
   1203static void
   1204delete_preset(struct snd_sf_list *sflist, struct snd_sf_zone *zp)
   1205{
   1206	int index;
   1207	struct snd_sf_zone *p;
   1208
   1209	index = get_index(zp->bank, zp->instr, zp->v.low);
   1210	if (index < 0)
   1211		return;
   1212	for (p = sflist->presets[index]; p; p = p->next_instr) {
   1213		while (p->next_instr == zp) {
   1214			p->next_instr = zp->next_instr;
   1215			zp = zp->next_zone;
   1216			if (zp == NULL)
   1217				return;
   1218		}
   1219	}
   1220}
   1221
   1222
   1223/*
   1224 * Search matching zones from preset table.
   1225 * The note can be rewritten by preset mapping (alias).
   1226 * The found zones are stored on 'table' array.  max_layers defines
   1227 * the maximum number of elements in this array.
   1228 * This function returns the number of found zones.  0 if not found.
   1229 */
   1230int
   1231snd_soundfont_search_zone(struct snd_sf_list *sflist, int *notep, int vel,
   1232			  int preset, int bank,
   1233			  int def_preset, int def_bank,
   1234			  struct snd_sf_zone **table, int max_layers)
   1235{
   1236	int nvoices;
   1237	unsigned long flags;
   1238
   1239	/* this function is supposed to be called atomically,
   1240	 * so we check the lock.  if it's busy, just returns 0 to
   1241	 * tell the caller the busy state
   1242	 */
   1243	spin_lock_irqsave(&sflist->lock, flags);
   1244	if (sflist->presets_locked) {
   1245		spin_unlock_irqrestore(&sflist->lock, flags);
   1246		return 0;
   1247	}
   1248	nvoices = search_zones(sflist, notep, vel, preset, bank,
   1249			       table, max_layers, 0);
   1250	if (! nvoices) {
   1251		if (preset != def_preset || bank != def_bank)
   1252			nvoices = search_zones(sflist, notep, vel,
   1253					       def_preset, def_bank,
   1254					       table, max_layers, 0);
   1255	}
   1256	spin_unlock_irqrestore(&sflist->lock, flags);
   1257	return nvoices;
   1258}
   1259
   1260
   1261/*
   1262 * search the first matching zone
   1263 */
   1264static struct snd_sf_zone *
   1265search_first_zone(struct snd_sf_list *sflist, int bank, int preset, int key)
   1266{
   1267	int index;
   1268	struct snd_sf_zone *zp;
   1269
   1270	index = get_index(bank, preset, key);
   1271	if (index < 0)
   1272		return NULL;
   1273	for (zp = sflist->presets[index]; zp; zp = zp->next_instr) {
   1274		if (zp->instr == preset && zp->bank == bank)
   1275			return zp;
   1276	}
   1277	return NULL;
   1278}
   1279
   1280
   1281/*
   1282 * search matching zones from sflist.  can be called recursively.
   1283 */
   1284static int
   1285search_zones(struct snd_sf_list *sflist, int *notep, int vel,
   1286	     int preset, int bank, struct snd_sf_zone **table,
   1287	     int max_layers, int level)
   1288{
   1289	struct snd_sf_zone *zp;
   1290	int nvoices;
   1291
   1292	zp = search_first_zone(sflist, bank, preset, *notep);
   1293	nvoices = 0;
   1294	for (; zp; zp = zp->next_zone) {
   1295		if (*notep >= zp->v.low && *notep <= zp->v.high &&
   1296		    vel >= zp->v.vellow && vel <= zp->v.velhigh) {
   1297			if (zp->mapped) {
   1298				/* search preset mapping (aliasing) */
   1299				int key = zp->v.fixkey;
   1300				preset = zp->v.start;
   1301				bank = zp->v.end;
   1302
   1303				if (level > 5) /* too deep alias level */
   1304					return 0;
   1305				if (key < 0)
   1306					key = *notep;
   1307				nvoices = search_zones(sflist, &key, vel,
   1308						       preset, bank, table,
   1309						       max_layers, level + 1);
   1310				if (nvoices > 0)
   1311					*notep = key;
   1312				break;
   1313			}
   1314			table[nvoices++] = zp;
   1315			if (nvoices >= max_layers)
   1316				break;
   1317		}
   1318	}
   1319
   1320	return nvoices;
   1321}
   1322
   1323
   1324/* calculate the index of preset table:
   1325 * drums are mapped from 128 to 255 according to its note key.
   1326 * other instruments are mapped from 0 to 127.
   1327 * if the index is out of range, return -1.
   1328 */
   1329static int
   1330get_index(int bank, int instr, int key)
   1331{
   1332	int index;
   1333	if (SF_IS_DRUM_BANK(bank))
   1334		index = key + SF_MAX_INSTRUMENTS;
   1335	else
   1336		index = instr;
   1337	index = index % SF_MAX_PRESETS;
   1338	if (index < 0)
   1339		return -1;
   1340	return index;
   1341}
   1342
   1343/*
   1344 * Initialise the sflist structure.
   1345 */
   1346static void
   1347snd_sf_init(struct snd_sf_list *sflist)
   1348{
   1349	memset(sflist->presets, 0, sizeof(sflist->presets));
   1350
   1351	sflist->mem_used = 0;
   1352	sflist->currsf = NULL;
   1353	sflist->open_client = -1;
   1354	sflist->fonts = NULL;
   1355	sflist->fonts_size = 0;
   1356	sflist->zone_counter = 0;
   1357	sflist->sample_counter = 0;
   1358	sflist->zone_locked = 0;
   1359	sflist->sample_locked = 0;
   1360}
   1361
   1362/*
   1363 * Release all list records
   1364 */
   1365static void
   1366snd_sf_clear(struct snd_sf_list *sflist)
   1367{
   1368	struct snd_soundfont *sf, *nextsf;
   1369	struct snd_sf_zone *zp, *nextzp;
   1370	struct snd_sf_sample *sp, *nextsp;
   1371
   1372	for (sf = sflist->fonts; sf; sf = nextsf) {
   1373		nextsf = sf->next;
   1374		for (zp = sf->zones; zp; zp = nextzp) {
   1375			nextzp = zp->next;
   1376			kfree(zp);
   1377		}
   1378		for (sp = sf->samples; sp; sp = nextsp) {
   1379			nextsp = sp->next;
   1380			if (sflist->callback.sample_free)
   1381				sflist->callback.sample_free(sflist->callback.private_data,
   1382							     sp, sflist->memhdr);
   1383			kfree(sp);
   1384		}
   1385		kfree(sf);
   1386	}
   1387
   1388	snd_sf_init(sflist);
   1389}
   1390
   1391
   1392/*
   1393 * Create a new sflist structure
   1394 */
   1395struct snd_sf_list *
   1396snd_sf_new(struct snd_sf_callback *callback, struct snd_util_memhdr *hdr)
   1397{
   1398	struct snd_sf_list *sflist;
   1399
   1400	sflist = kzalloc(sizeof(*sflist), GFP_KERNEL);
   1401	if (!sflist)
   1402		return NULL;
   1403
   1404	mutex_init(&sflist->presets_mutex);
   1405	spin_lock_init(&sflist->lock);
   1406	sflist->memhdr = hdr;
   1407
   1408	if (callback)
   1409		sflist->callback = *callback;
   1410
   1411	snd_sf_init(sflist);
   1412	return sflist;
   1413}
   1414
   1415
   1416/*
   1417 * Free everything allocated off the sflist structure.
   1418 */
   1419void
   1420snd_sf_free(struct snd_sf_list *sflist)
   1421{
   1422	if (sflist == NULL)
   1423		return;
   1424	
   1425	lock_preset(sflist);
   1426	if (sflist->callback.sample_reset)
   1427		sflist->callback.sample_reset(sflist->callback.private_data);
   1428	snd_sf_clear(sflist);
   1429	unlock_preset(sflist);
   1430
   1431	kfree(sflist);
   1432}
   1433
   1434/*
   1435 * Remove all samples
   1436 * The soundcard should be silent before calling this function.
   1437 */
   1438int
   1439snd_soundfont_remove_samples(struct snd_sf_list *sflist)
   1440{
   1441	lock_preset(sflist);
   1442	if (sflist->callback.sample_reset)
   1443		sflist->callback.sample_reset(sflist->callback.private_data);
   1444	snd_sf_clear(sflist);
   1445	unlock_preset(sflist);
   1446
   1447	return 0;
   1448}
   1449
   1450/*
   1451 * Remove unlocked samples.
   1452 * The soundcard should be silent before calling this function.
   1453 */
   1454int
   1455snd_soundfont_remove_unlocked(struct snd_sf_list *sflist)
   1456{
   1457	struct snd_soundfont *sf;
   1458	struct snd_sf_zone *zp, *nextzp;
   1459	struct snd_sf_sample *sp, *nextsp;
   1460
   1461	lock_preset(sflist);
   1462
   1463	if (sflist->callback.sample_reset)
   1464		sflist->callback.sample_reset(sflist->callback.private_data);
   1465
   1466	/* to be sure */
   1467	memset(sflist->presets, 0, sizeof(sflist->presets));
   1468
   1469	for (sf = sflist->fonts; sf; sf = sf->next) {
   1470		for (zp = sf->zones; zp; zp = nextzp) {
   1471			if (zp->counter < sflist->zone_locked)
   1472				break;
   1473			nextzp = zp->next;
   1474			sf->zones = nextzp;
   1475			kfree(zp);
   1476		}
   1477
   1478		for (sp = sf->samples; sp; sp = nextsp) {
   1479			if (sp->counter < sflist->sample_locked)
   1480				break;
   1481			nextsp = sp->next;
   1482			sf->samples = nextsp;
   1483			sflist->mem_used -= sp->v.truesize;
   1484			if (sflist->callback.sample_free)
   1485				sflist->callback.sample_free(sflist->callback.private_data,
   1486							     sp, sflist->memhdr);
   1487			kfree(sp);
   1488		}
   1489	}
   1490
   1491	sflist->zone_counter = sflist->zone_locked;
   1492	sflist->sample_counter = sflist->sample_locked;
   1493
   1494	rebuild_presets(sflist);
   1495
   1496	unlock_preset(sflist);
   1497	return 0;
   1498}