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}
1499