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 pararameters 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	if ((zp = kzalloc(sizeof(*zp), GFP_KERNEL)) == NULL)
353		return NULL;
354	zp->next = sf->zones;
355	sf->zones = zp;
356
357	init_voice_info(&zp->v);
358
359	set_zone_counter(sflist, sf, zp);
360	return zp;
361}
362
363
364/*
365 * increment sample counter
366 */
367static void
368set_sample_counter(struct snd_sf_list *sflist, struct snd_soundfont *sf,
369		   struct snd_sf_sample *sp)
370{
371	sp->counter = sflist->sample_counter++;
372	if (sf->type & SNDRV_SFNT_PAT_LOCKED)
373		sflist->sample_locked = sflist->sample_counter;
374}
375
376/*
377 * allocate a new sample list record
378 */
379static struct snd_sf_sample *
380sf_sample_new(struct snd_sf_list *sflist, struct snd_soundfont *sf)
381{
382	struct snd_sf_sample *sp;
383
384	if ((sp = kzalloc(sizeof(*sp), GFP_KERNEL)) == NULL)
385		return NULL;
386
387	sp->next = sf->samples;
388	sf->samples = sp;
389
390	set_sample_counter(sflist, sf, sp);
391	return sp;
392}
393
394/*
395 * delete sample list -- this is an exceptional job.
396 * only the last allocated sample can be deleted.
397 */
398static void
399sf_sample_delete(struct snd_sf_list *sflist, struct snd_soundfont *sf,
400		 struct snd_sf_sample *sp)
401{
402	/* only last sample is accepted */
403	if (sp == sf->samples) {
404		sf->samples = sp->next;
405		kfree(sp);
406	}
407}
408
409
410/* load voice map */
411static int
412load_map(struct snd_sf_list *sflist, const void __user *data, int count)
413{
414	struct snd_sf_zone *zp, *prevp;
415	struct snd_soundfont *sf;
416	struct soundfont_voice_map map;
417
418	/* get the link info */
419	if (count < (int)sizeof(map))
420		return -EINVAL;
421	if (copy_from_user(&map, data, sizeof(map)))
422		return -EFAULT;
423
424	if (map.map_instr < 0 || map.map_instr >= SF_MAX_INSTRUMENTS)
425		return -EINVAL;
426
427	sf = newsf(sflist, SNDRV_SFNT_PAT_TYPE_MAP|SNDRV_SFNT_PAT_SHARED, NULL);
428	if (sf == NULL)
429		return -ENOMEM;
430
431	prevp = NULL;
432	for (zp = sf->zones; zp; prevp = zp, zp = zp->next) {
433		if (zp->mapped &&
434		    zp->instr == map.map_instr &&
435		    zp->bank == map.map_bank &&
436		    zp->v.low == map.map_key &&
437		    zp->v.start == map.src_instr &&
438		    zp->v.end == map.src_bank &&
439		    zp->v.fixkey == map.src_key) {
440			/* the same mapping is already present */
441			/* relink this record to the link head */
442			if (prevp) {
443				prevp->next = zp->next;
444				zp->next = sf->zones;
445				sf->zones = zp;
446			}
447			/* update the counter */
448			set_zone_counter(sflist, sf, zp);
449			return 0;
450		}
451	}
452
453	/* create a new zone */
454	if ((zp = sf_zone_new(sflist, sf)) == NULL)
455		return -ENOMEM;
456
457	zp->bank = map.map_bank;
458	zp->instr = map.map_instr;
459	zp->mapped = 1;
460	if (map.map_key >= 0) {
461		zp->v.low = map.map_key;
462		zp->v.high = map.map_key;
463	}
464	zp->v.start = map.src_instr;
465	zp->v.end = map.src_bank;
466	zp->v.fixkey = map.src_key;
467	zp->v.sf_id = sf->id;
468
469	add_preset(sflist, zp);
470
471	return 0;
472}
473
474
475/* remove the present instrument layers */
476static int
477remove_info(struct snd_sf_list *sflist, struct snd_soundfont *sf,
478	    int bank, int instr)
479{
480	struct snd_sf_zone *prev, *next, *p;
481	int removed = 0;
482
483	prev = NULL;
484	for (p = sf->zones; p; p = next) {
485		next = p->next;
486		if (! p->mapped &&
487		    p->bank == bank && p->instr == instr) {
488			/* remove this layer */
489			if (prev)
490				prev->next = next;
491			else
492				sf->zones = next;
493			removed++;
494			kfree(p);
495		} else
496			prev = p;
497	}
498	if (removed)
499		rebuild_presets(sflist);
500	return removed;
501}
502
503
504/*
505 * Read an info record from the user buffer and save it on the current
506 * open soundfont.
507 */
508static int
509load_info(struct snd_sf_list *sflist, const void __user *data, long count)
510{
511	struct snd_soundfont *sf;
512	struct snd_sf_zone *zone;
513	struct soundfont_voice_rec_hdr hdr;
514	int i;
515
516	/* patch must be opened */
517	if ((sf = sflist->currsf) == NULL)
518		return -EINVAL;
519
520	if (is_special_type(sf->type))
521		return -EINVAL;
522
523	if (count < (long)sizeof(hdr)) {
524		printk(KERN_ERR "Soundfont error: invalid patch zone length\n");
525		return -EINVAL;
526	}
527	if (copy_from_user((char*)&hdr, data, sizeof(hdr)))
528		return -EFAULT;
529
530	data += sizeof(hdr);
531	count -= sizeof(hdr);
532
533	if (hdr.nvoices <= 0 || hdr.nvoices >= 100) {
534		printk(KERN_ERR "Soundfont error: Illegal voice number %d\n",
535		       hdr.nvoices);
536		return -EINVAL;
537	}
538
539	if (count < (long)sizeof(struct soundfont_voice_info) * hdr.nvoices) {
540		printk(KERN_ERR "Soundfont Error: "
541		       "patch length(%ld) is smaller than nvoices(%d)\n",
542		       count, hdr.nvoices);
543		return -EINVAL;
544	}
545
546	switch (hdr.write_mode) {
547	case SNDRV_SFNT_WR_EXCLUSIVE:
548		/* exclusive mode - if the instrument already exists,
549		   return error */
550		for (zone = sf->zones; zone; zone = zone->next) {
551			if (!zone->mapped &&
552			    zone->bank == hdr.bank &&
553			    zone->instr == hdr.instr)
554				return -EINVAL;
555		}
556		break;
557	case SNDRV_SFNT_WR_REPLACE:
558		/* replace mode - remove the instrument if it already exists */
559		remove_info(sflist, sf, hdr.bank, hdr.instr);
560		break;
561	}
562
563	for (i = 0; i < hdr.nvoices; i++) {
564		struct snd_sf_zone tmpzone;
565
566		/* copy awe_voice_info parameters */
567		if (copy_from_user(&tmpzone.v, data, sizeof(tmpzone.v))) {
568			return -EFAULT;
569		}
570
571		data += sizeof(tmpzone.v);
572		count -= sizeof(tmpzone.v);
573
574		tmpzone.bank = hdr.bank;
575		tmpzone.instr = hdr.instr;
576		tmpzone.mapped = 0;
577		tmpzone.v.sf_id = sf->id;
578		if (tmpzone.v.mode & SNDRV_SFNT_MODE_INIT_PARM)
579			init_voice_parm(&tmpzone.v.parm);
580
581		/* create a new zone */
582		if ((zone = sf_zone_new(sflist, sf)) == NULL) {
583			return -ENOMEM;
584		}
585
586		/* copy the temporary data */
587		zone->bank = tmpzone.bank;
588		zone->instr = tmpzone.instr;
589		zone->v = tmpzone.v;
590
591		/* look up the sample */
592		zone->sample = set_sample(sf, &zone->v);
593	}
594
595	return 0;
596}
597
598
599/* initialize voice_info record */
600static void
601init_voice_info(struct soundfont_voice_info *avp)
602{
603	memset(avp, 0, sizeof(*avp));
604
605	avp->root = 60;
606	avp->high = 127;
607	avp->velhigh = 127;
608	avp->fixkey = -1;
609	avp->fixvel = -1;
610	avp->fixpan = -1;
611	avp->pan = -1;
612	avp->amplitude = 127;
613	avp->scaleTuning = 100;
614
615	init_voice_parm(&avp->parm);
616}
617
618/* initialize voice_parm record:
619 * Env1/2: delay=0, attack=0, hold=0, sustain=0, decay=0, release=0.
620 * Vibrato and Tremolo effects are zero.
621 * Cutoff is maximum.
622 * Chorus and Reverb effects are zero.
623 */
624static void
625init_voice_parm(struct soundfont_voice_parm *pp)
626{
627	memset(pp, 0, sizeof(*pp));
628
629	pp->moddelay = 0x8000;
630	pp->modatkhld = 0x7f7f;
631	pp->moddcysus = 0x7f7f;
632	pp->modrelease = 0x807f;
633
634	pp->voldelay = 0x8000;
635	pp->volatkhld = 0x7f7f;
636	pp->voldcysus = 0x7f7f;
637	pp->volrelease = 0x807f;
638
639	pp->lfo1delay = 0x8000;
640	pp->lfo2delay = 0x8000;
641
642	pp->cutoff = 0xff;
643}
644
645/* search the specified sample */
646static struct snd_sf_sample *
647set_sample(struct snd_soundfont *sf, struct soundfont_voice_info *avp)
648{
649	struct snd_sf_sample *sample;
650
651	sample = find_sample(sf, avp->sample);
652	if (sample == NULL)
653		return NULL;
654
655	/* add in the actual sample offsets:
656	 * The voice_info addresses define only the relative offset
657	 * from sample pointers.  Here we calculate the actual DRAM
658	 * offset from sample pointers.
659	 */
660	avp->start += sample->v.start;
661	avp->end += sample->v.end;
662	avp->loopstart += sample->v.loopstart;
663	avp->loopend += sample->v.loopend;
664
665	/* copy mode flags */
666	avp->sample_mode = sample->v.mode_flags;
667
668	return sample;
669}
670
671/* find the sample pointer with the given id in the soundfont */
672static struct snd_sf_sample *
673find_sample(struct snd_soundfont *sf, int sample_id)
674{
675	struct snd_sf_sample *p;
676
677	if (sf == NULL)
678		return NULL;
679
680	for (p = sf->samples; p; p = p->next) {
681		if (p->v.sample == sample_id)
682			return p;
683	}
684	return NULL;
685}
686
687
688/*
689 * Load sample information, this can include data to be loaded onto
690 * the soundcard.  It can also just be a pointer into soundcard ROM.
691 * If there is data it will be written to the soundcard via the callback
692 * routine.
693 */
694static int
695load_data(struct snd_sf_list *sflist, const void __user *data, long count)
696{
697	struct snd_soundfont *sf;
698	struct soundfont_sample_info sample_info;
699	struct snd_sf_sample *sp;
700	long off;
701
702	/* patch must be opened */
703	if ((sf = sflist->currsf) == NULL)
704		return -EINVAL;
705
706	if (is_special_type(sf->type))
707		return -EINVAL;
708
709	if (copy_from_user(&sample_info, data, sizeof(sample_info)))
710		return -EFAULT;
711
712	off = sizeof(sample_info);
713
714	if (sample_info.size != (count-off)/2)
715		return -EINVAL;
716
717	/* Check for dup */
718	if (find_sample(sf, sample_info.sample)) {
719		/* if shared sample, skip this data */
720		if (sf->type & SNDRV_SFNT_PAT_SHARED)
721			return 0;
722		return -EINVAL;
723	}
724
725	/* Allocate a new sample structure */
726	if ((sp = sf_sample_new(sflist, sf)) == NULL)
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 = sp->v.size;
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 + off, count - off);
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 approxmimation 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_sf_list *sflist, const char __user *data,
939	      long count, int client)
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		snd_printk(KERN_ERR "patch record too small %ld\n", count);
950		return -EINVAL;
951	}
952	if (copy_from_user(&patch, data, sizeof(patch)))
953		return -EFAULT;
954
955	count -= sizeof(patch);
956	data += sizeof(patch);
957
958	sf = newsf(sflist, SNDRV_SFNT_PAT_TYPE_GUS|SNDRV_SFNT_PAT_SHARED, NULL);
959	if (sf == NULL)
960		return -ENOMEM;
961	if ((smp = sf_sample_new(sflist, sf)) == NULL)
962		return -ENOMEM;
963	sample_id = sflist->sample_counter;
964	smp->v.sample = sample_id;
965	smp->v.start = 0;
966	smp->v.end = patch.len;
967	smp->v.loopstart = patch.loop_start;
968	smp->v.loopend = patch.loop_end;
969	smp->v.size = patch.len;
970
971	/* set up mode flags */
972	smp->v.mode_flags = 0;
973	if (!(patch.mode & WAVE_16_BITS))
974		smp->v.mode_flags |= SNDRV_SFNT_SAMPLE_8BITS;
975	if (patch.mode & WAVE_UNSIGNED)
976		smp->v.mode_flags |= SNDRV_SFNT_SAMPLE_UNSIGNED;
977	smp->v.mode_flags |= SNDRV_SFNT_SAMPLE_NO_BLANK;
978	if (!(patch.mode & (WAVE_LOOPING|WAVE_BIDIR_LOOP|WAVE_LOOP_BACK)))
979		smp->v.mode_flags |= SNDRV_SFNT_SAMPLE_SINGLESHOT;
980	if (patch.mode & WAVE_BIDIR_LOOP)
981		smp->v.mode_flags |= SNDRV_SFNT_SAMPLE_BIDIR_LOOP;
982	if (patch.mode & WAVE_LOOP_BACK)
983		smp->v.mode_flags |= SNDRV_SFNT_SAMPLE_REVERSE_LOOP;
984
985	if (patch.mode & WAVE_16_BITS) {
986		/* convert to word offsets */
987		smp->v.size /= 2;
988		smp->v.end /= 2;
989		smp->v.loopstart /= 2;
990		smp->v.loopend /= 2;
991	}
992	/*smp->v.loopend++;*/
993
994	smp->v.dummy = 0;
995	smp->v.truesize = 0;
996	smp->v.sf_id = sf->id;
997
998	/* set up voice info */
999	if ((zone = sf_zone_new(sflist, sf)) == NULL) {
1000		sf_sample_delete(sflist, sf, smp);
1001		return -ENOMEM;
1002	}
1003
1004	/*
1005	 * load wave data
1006	 */
1007	if (sflist->callback.sample_new) {
1008		rc = sflist->callback.sample_new
1009			(sflist->callback.private_data, smp, sflist->memhdr,
1010			 data, count);
1011		if (rc < 0) {
1012			sf_sample_delete(sflist, sf, smp);
1013			kfree(zone);
1014			return rc;
1015		}
1016		/* memory offset is updated after */
1017	}
1018
1019	/* update the memory offset here */
1020	sflist->mem_used += smp->v.truesize;
1021
1022	zone->v.sample = sample_id; /* the last sample */
1023	zone->v.rate_offset = calc_rate_offset(patch.base_freq);
1024	note = freq_to_note(patch.base_note);
1025	zone->v.root = note / 100;
1026	zone->v.tune = -(note % 100);
1027	zone->v.low = (freq_to_note(patch.low_note) + 99) / 100;
1028	zone->v.high = freq_to_note(patch.high_note) / 100;
1029	/* panning position; -128 - 127 => 0-127 */
1030	zone->v.pan = (patch.panning + 128) / 2;
1031#if 0
1032	snd_printk(KERN_DEBUG
1033		   "gus: basefrq=%d (ofs=%d) root=%d,tune=%d, range:%d-%d\n",
1034		   (int)patch.base_freq, zone->v.rate_offset,
1035		   zone->v.root, zone->v.tune, zone->v.low, zone->v.high);
1036#endif
1037
1038	/* detuning is ignored */
1039	/* 6points volume envelope */
1040	if (patch.mode & WAVE_ENVELOPES) {
1041		int attack, hold, decay, release;
1042		attack = calc_gus_envelope_time
1043			(patch.env_rate[0], 0, patch.env_offset[0]);
1044		hold = calc_gus_envelope_time
1045			(patch.env_rate[1], patch.env_offset[0],
1046			 patch.env_offset[1]);
1047		decay = calc_gus_envelope_time
1048			(patch.env_rate[2], patch.env_offset[1],
1049			 patch.env_offset[2]);
1050		release = calc_gus_envelope_time
1051			(patch.env_rate[3], patch.env_offset[1],
1052			 patch.env_offset[4]);
1053		release += calc_gus_envelope_time
1054			(patch.env_rate[4], patch.env_offset[3],
1055			 patch.env_offset[4]);
1056		release += calc_gus_envelope_time
1057			(patch.env_rate[5], patch.env_offset[4],
1058			 patch.env_offset[5]);
1059		zone->v.parm.volatkhld =
1060			(snd_sf_calc_parm_hold(hold) << 8) |
1061			snd_sf_calc_parm_attack(attack);
1062		zone->v.parm.voldcysus = (calc_gus_sustain(patch.env_offset[2]) << 8) |
1063			snd_sf_calc_parm_decay(decay);
1064		zone->v.parm.volrelease = 0x8000 | snd_sf_calc_parm_decay(release);
1065		zone->v.attenuation = calc_gus_attenuation(patch.env_offset[0]);
1066#if 0
1067		snd_printk(KERN_DEBUG
1068			   "gus: atkhld=%x, dcysus=%x, volrel=%x, att=%d\n",
1069			   zone->v.parm.volatkhld,
1070			   zone->v.parm.voldcysus,
1071			   zone->v.parm.volrelease,
1072			   zone->v.attenuation);
1073#endif
1074	}
1075
1076	/* fast release */
1077	if (patch.mode & WAVE_FAST_RELEASE) {
1078		zone->v.parm.volrelease = 0x807f;
1079	}
1080
1081	/* tremolo effect */
1082	if (patch.mode & WAVE_TREMOLO) {
1083		int rate = (patch.tremolo_rate * 1000 / 38) / 42;
1084		zone->v.parm.tremfrq = ((patch.tremolo_depth / 2) << 8) | rate;
1085	}
1086	/* vibrato effect */
1087	if (patch.mode & WAVE_VIBRATO) {
1088		int rate = (patch.vibrato_rate * 1000 / 38) / 42;
1089		zone->v.parm.fm2frq2 = ((patch.vibrato_depth / 6) << 8) | rate;
1090	}
1091
1092	/* scale_freq, scale_factor, volume, and fractions not implemented */
1093
1094	if (!(smp->v.mode_flags & SNDRV_SFNT_SAMPLE_SINGLESHOT))
1095		zone->v.mode = SNDRV_SFNT_MODE_LOOPING;
1096	else
1097		zone->v.mode = 0;
1098
1099	/* append to the tail of the list */
1100	/*zone->bank = ctrls[AWE_MD_GUS_BANK];*/
1101	zone->bank = 0;
1102	zone->instr = patch.instr_no;
1103	zone->mapped = 0;
1104	zone->v.sf_id = sf->id;
1105
1106	zone->sample = set_sample(sf, &zone->v);
1107
1108	/* rebuild preset now */
1109	add_preset(sflist, zone);
1110
1111	return 0;
1112}
1113
1114/* load GUS patch */
1115int
1116snd_soundfont_load_guspatch(struct snd_sf_list *sflist, const char __user *data,
1117			    long count, int client)
1118{
1119	int rc;
1120	lock_preset(sflist);
1121	rc = load_guspatch(sflist, data, count, client);
1122	unlock_preset(sflist);
1123	return rc;
1124}
1125
1126
1127/*
1128 * Rebuild the preset table.  This is like a hash table in that it allows
1129 * quick access to the zone information.  For each preset there are zone
1130 * structures linked by next_instr and by next_zone.  Former is the whole
1131 * link for this preset, and latter is the link for zone (i.e. instrument/
1132 * bank/key combination).
1133 */
1134static void
1135rebuild_presets(struct snd_sf_list *sflist)
1136{
1137	struct snd_soundfont *sf;
1138	struct snd_sf_zone *cur;
1139
1140	/* clear preset table */
1141	memset(sflist->presets, 0, sizeof(sflist->presets));
1142
1143	/* search all fonts and insert each font */
1144	for (sf = sflist->fonts; sf; sf = sf->next) {
1145		for (cur = sf->zones; cur; cur = cur->next) {
1146			if (! cur->mapped && cur->sample == NULL) {
1147				/* try again to search the corresponding sample */
1148				cur->sample = set_sample(sf, &cur->v);
1149				if (cur->sample == NULL)
1150					continue;
1151			}
1152
1153			add_preset(sflist, cur);
1154		}
1155	}
1156}
1157
1158
1159/*
1160 * add the given zone to preset table
1161 */
1162static void
1163add_preset(struct snd_sf_list *sflist, struct snd_sf_zone *cur)
1164{
1165	struct snd_sf_zone *zone;
1166	int index;
1167
1168	zone = search_first_zone(sflist, cur->bank, cur->instr, cur->v.low);
1169	if (zone && zone->v.sf_id != cur->v.sf_id) {
1170		/* different instrument was already defined */
1171		struct snd_sf_zone *p;
1172		/* compare the allocated time */
1173		for (p = zone; p; p = p->next_zone) {
1174			if (p->counter > cur->counter)
1175				/* the current is older.. skipped */
1176				return;
1177		}
1178		/* remove old zones */
1179		delete_preset(sflist, zone);
1180		zone = NULL; /* do not forget to clear this! */
1181	}
1182
1183	/* prepend this zone */
1184	if ((index = get_index(cur->bank, cur->instr, cur->v.low)) < 0)
1185		return;
1186	cur->next_zone = zone; /* zone link */
1187	cur->next_instr = sflist->presets[index]; /* preset table link */
1188	sflist->presets[index] = cur;
1189}
1190
1191/*
1192 * delete the given zones from preset_table
1193 */
1194static void
1195delete_preset(struct snd_sf_list *sflist, struct snd_sf_zone *zp)
1196{
1197	int index;
1198	struct snd_sf_zone *p;
1199
1200	if ((index = get_index(zp->bank, zp->instr, zp->v.low)) < 0)
1201		return;
1202	for (p = sflist->presets[index]; p; p = p->next_instr) {
1203		while (p->next_instr == zp) {
1204			p->next_instr = zp->next_instr;
1205			zp = zp->next_zone;
1206			if (zp == NULL)
1207				return;
1208		}
1209	}
1210}
1211
1212
1213/*
1214 * Search matching zones from preset table.
1215 * The note can be rewritten by preset mapping (alias).
1216 * The found zones are stored on 'table' array.  max_layers defines
1217 * the maximum number of elements in this array.
1218 * This function returns the number of found zones.  0 if not found.
1219 */
1220int
1221snd_soundfont_search_zone(struct snd_sf_list *sflist, int *notep, int vel,
1222			  int preset, int bank,
1223			  int def_preset, int def_bank,
1224			  struct snd_sf_zone **table, int max_layers)
1225{
1226	int nvoices;
1227	unsigned long flags;
1228
1229	/* this function is supposed to be called atomically,
1230	 * so we check the lock.  if it's busy, just returns 0 to
1231	 * tell the caller the busy state
1232	 */
1233	spin_lock_irqsave(&sflist->lock, flags);
1234	if (sflist->presets_locked) {
1235		spin_unlock_irqrestore(&sflist->lock, flags);
1236		return 0;
1237	}
1238	nvoices = search_zones(sflist, notep, vel, preset, bank,
1239			       table, max_layers, 0);
1240	if (! nvoices) {
1241		if (preset != def_preset || bank != def_bank)
1242			nvoices = search_zones(sflist, notep, vel,
1243					       def_preset, def_bank,
1244					       table, max_layers, 0);
1245	}
1246	spin_unlock_irqrestore(&sflist->lock, flags);
1247	return nvoices;
1248}
1249
1250
1251/*
1252 * search the first matching zone
1253 */
1254static struct snd_sf_zone *
1255search_first_zone(struct snd_sf_list *sflist, int bank, int preset, int key)
1256{
1257	int index;
1258	struct snd_sf_zone *zp;
1259
1260	if ((index = get_index(bank, preset, key)) < 0)
1261		return NULL;
1262	for (zp = sflist->presets[index]; zp; zp = zp->next_instr) {
1263		if (zp->instr == preset && zp->bank == bank)
1264			return zp;
1265	}
1266	return NULL;
1267}
1268
1269
1270/*
1271 * search matching zones from sflist.  can be called recursively.
1272 */
1273static int
1274search_zones(struct snd_sf_list *sflist, int *notep, int vel,
1275	     int preset, int bank, struct snd_sf_zone **table,
1276	     int max_layers, int level)
1277{
1278	struct snd_sf_zone *zp;
1279	int nvoices;
1280
1281	zp = search_first_zone(sflist, bank, preset, *notep);
1282	nvoices = 0;
1283	for (; zp; zp = zp->next_zone) {
1284		if (*notep >= zp->v.low && *notep <= zp->v.high &&
1285		    vel >= zp->v.vellow && vel <= zp->v.velhigh) {
1286			if (zp->mapped) {
1287				/* search preset mapping (aliasing) */
1288				int key = zp->v.fixkey;
1289				preset = zp->v.start;
1290				bank = zp->v.end;
1291
1292				if (level > 5) /* too deep alias level */
1293					return 0;
1294				if (key < 0)
1295					key = *notep;
1296				nvoices = search_zones(sflist, &key, vel,
1297						       preset, bank, table,
1298						       max_layers, level + 1);
1299				if (nvoices > 0)
1300					*notep = key;
1301				break;
1302			}
1303			table[nvoices++] = zp;
1304			if (nvoices >= max_layers)
1305				break;
1306		}
1307	}
1308
1309	return nvoices;
1310}
1311
1312
1313/* calculate the index of preset table:
1314 * drums are mapped from 128 to 255 according to its note key.
1315 * other instruments are mapped from 0 to 127.
1316 * if the index is out of range, return -1.
1317 */
1318static int
1319get_index(int bank, int instr, int key)
1320{
1321	int index;
1322	if (SF_IS_DRUM_BANK(bank))
1323		index = key + SF_MAX_INSTRUMENTS;
1324	else
1325		index = instr;
1326	index = index % SF_MAX_PRESETS;
1327	if (index < 0)
1328		return -1;
1329	return index;
1330}
1331
1332/*
1333 * Initialise the sflist structure.
1334 */
1335static void
1336snd_sf_init(struct snd_sf_list *sflist)
1337{
1338	memset(sflist->presets, 0, sizeof(sflist->presets));
1339
1340	sflist->mem_used = 0;
1341	sflist->currsf = NULL;
1342	sflist->open_client = -1;
1343	sflist->fonts = NULL;
1344	sflist->fonts_size = 0;
1345	sflist->zone_counter = 0;
1346	sflist->sample_counter = 0;
1347	sflist->zone_locked = 0;
1348	sflist->sample_locked = 0;
1349}
1350
1351/*
1352 * Release all list records
1353 */
1354static void
1355snd_sf_clear(struct snd_sf_list *sflist)
1356{
1357	struct snd_soundfont *sf, *nextsf;
1358	struct snd_sf_zone *zp, *nextzp;
1359	struct snd_sf_sample *sp, *nextsp;
1360
1361	for (sf = sflist->fonts; sf; sf = nextsf) {
1362		nextsf = sf->next;
1363		for (zp = sf->zones; zp; zp = nextzp) {
1364			nextzp = zp->next;
1365			kfree(zp);
1366		}
1367		for (sp = sf->samples; sp; sp = nextsp) {
1368			nextsp = sp->next;
1369			if (sflist->callback.sample_free)
1370				sflist->callback.sample_free(sflist->callback.private_data,
1371							     sp, sflist->memhdr);
1372			kfree(sp);
1373		}
1374		kfree(sf);
1375	}
1376
1377	snd_sf_init(sflist);
1378}
1379
1380
1381/*
1382 * Create a new sflist structure
1383 */
1384struct snd_sf_list *
1385snd_sf_new(struct snd_sf_callback *callback, struct snd_util_memhdr *hdr)
1386{
1387	struct snd_sf_list *sflist;
1388
1389	if ((sflist = kzalloc(sizeof(*sflist), GFP_KERNEL)) == NULL)
1390		return NULL;
1391
1392	mutex_init(&sflist->presets_mutex);
1393	spin_lock_init(&sflist->lock);
1394	sflist->memhdr = hdr;
1395
1396	if (callback)
1397		sflist->callback = *callback;
1398
1399	snd_sf_init(sflist);
1400	return sflist;
1401}
1402
1403
1404/*
1405 * Free everything allocated off the sflist structure.
1406 */
1407void
1408snd_sf_free(struct snd_sf_list *sflist)
1409{
1410	if (sflist == NULL)
1411		return;
1412
1413	lock_preset(sflist);
1414	if (sflist->callback.sample_reset)
1415		sflist->callback.sample_reset(sflist->callback.private_data);
1416	snd_sf_clear(sflist);
1417	unlock_preset(sflist);
1418
1419	kfree(sflist);
1420}
1421
1422/*
1423 * Remove all samples
1424 * The soundcard should be silet before calling this function.
1425 */
1426int
1427snd_soundfont_remove_samples(struct snd_sf_list *sflist)
1428{
1429	lock_preset(sflist);
1430	if (sflist->callback.sample_reset)
1431		sflist->callback.sample_reset(sflist->callback.private_data);
1432	snd_sf_clear(sflist);
1433	unlock_preset(sflist);
1434
1435	return 0;
1436}
1437
1438/*
1439 * Remove unlocked samples.
1440 * The soundcard should be silent before calling this function.
1441 */
1442int
1443snd_soundfont_remove_unlocked(struct snd_sf_list *sflist)
1444{
1445	struct snd_soundfont *sf;
1446	struct snd_sf_zone *zp, *nextzp;
1447	struct snd_sf_sample *sp, *nextsp;
1448
1449	lock_preset(sflist);
1450
1451	if (sflist->callback.sample_reset)
1452		sflist->callback.sample_reset(sflist->callback.private_data);
1453
1454	/* to be sure */
1455	memset(sflist->presets, 0, sizeof(sflist->presets));
1456
1457	for (sf = sflist->fonts; sf; sf = sf->next) {
1458		for (zp = sf->zones; zp; zp = nextzp) {
1459			if (zp->counter < sflist->zone_locked)
1460				break;
1461			nextzp = zp->next;
1462			sf->zones = nextzp;
1463			kfree(zp);
1464		}
1465
1466		for (sp = sf->samples; sp; sp = nextsp) {
1467			if (sp->counter < sflist->sample_locked)
1468				break;
1469			nextsp = sp->next;
1470			sf->samples = nextsp;
1471			sflist->mem_used -= sp->v.truesize;
1472			if (sflist->callback.sample_free)
1473				sflist->callback.sample_free(sflist->callback.private_data,
1474							     sp, sflist->memhdr);
1475			kfree(sp);
1476		}
1477	}
1478
1479	sflist->zone_counter = sflist->zone_locked;
1480	sflist->sample_counter = sflist->sample_locked;
1481
1482	rebuild_presets(sflist);
1483
1484	unlock_preset(sflist);
1485	return 0;
1486}
1487