Linux Audio

Check our new training course

Open-source upstreaming

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