Linux Audio

Check our new training course

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}
v5.14.15
   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}