File Index
Files and directories
Sign in
FILE

soundfont.c

File preview with syntax highlighting.

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