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