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 
24 static int open_patch(struct snd_sf_list *sflist, const char __user *data,
25 		      int count, int client);
26 static struct snd_soundfont *newsf(struct snd_sf_list *sflist, int type, char *name);
27 static int is_identical_font(struct snd_soundfont *sf, int type, unsigned char *name);
28 static int close_patch(struct snd_sf_list *sflist);
29 static int probe_data(struct snd_sf_list *sflist, int sample_id);
30 static void set_zone_counter(struct snd_sf_list *sflist,
31 			     struct snd_soundfont *sf, struct snd_sf_zone *zp);
32 static struct snd_sf_zone *sf_zone_new(struct snd_sf_list *sflist,
33 				       struct snd_soundfont *sf);
34 static void set_sample_counter(struct snd_sf_list *sflist,
35 			       struct snd_soundfont *sf, struct snd_sf_sample *sp);
36 static struct snd_sf_sample *sf_sample_new(struct snd_sf_list *sflist,
37 					   struct snd_soundfont *sf);
38 static void sf_sample_delete(struct snd_sf_list *sflist,
39 			     struct snd_soundfont *sf, struct snd_sf_sample *sp);
40 static int load_map(struct snd_sf_list *sflist, const void __user *data, int count);
41 static int load_info(struct snd_sf_list *sflist, const void __user *data, long count);
42 static int remove_info(struct snd_sf_list *sflist, struct snd_soundfont *sf,
43 		       int bank, int instr);
44 static void init_voice_info(struct soundfont_voice_info *avp);
45 static void init_voice_parm(struct soundfont_voice_parm *pp);
46 static struct snd_sf_sample *set_sample(struct snd_soundfont *sf,
47 					struct soundfont_voice_info *avp);
48 static struct snd_sf_sample *find_sample(struct snd_soundfont *sf, int sample_id);
49 static int load_data(struct snd_sf_list *sflist, const void __user *data, long count);
50 static void rebuild_presets(struct snd_sf_list *sflist);
51 static void add_preset(struct snd_sf_list *sflist, struct snd_sf_zone *cur);
52 static void delete_preset(struct snd_sf_list *sflist, struct snd_sf_zone *zp);
53 static struct snd_sf_zone *search_first_zone(struct snd_sf_list *sflist,
54 					     int bank, int preset, int key);
55 static 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);
58 static int get_index(int bank, int instr, int key);
59 static void snd_sf_init(struct snd_sf_list *sflist);
60 static void snd_sf_clear(struct snd_sf_list *sflist);
61 
62 /*
63  * lock access to sflist
64  */
65 static void
lock_preset(struct snd_sf_list * sflist)66 lock_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  */
79 static void
unlock_preset(struct snd_sf_list * sflist)80 unlock_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  */
93 int
snd_soundfont_close_check(struct snd_sf_list * sflist,int client)94 snd_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  */
115 int
snd_soundfont_load(struct snd_sf_list * sflist,const void __user * data,long count,int client)116 snd_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) */
208 static inline int
is_special_type(int type)209 is_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 */
218 static int
open_patch(struct snd_sf_list * sflist,const char __user * data,int count,int client)219 open_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  */
256 static struct snd_soundfont *
newsf(struct snd_sf_list * sflist,int type,char * name)257 newsf(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 */
291 static int
is_identical_font(struct snd_soundfont * sf,int type,unsigned char * name)292 is_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  */
303 static int
close_patch(struct snd_sf_list * sflist)304 close_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 */
320 static int
probe_data(struct snd_sf_list * sflist,int sample_id)321 probe_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  */
335 static void
set_zone_counter(struct snd_sf_list * sflist,struct snd_soundfont * sf,struct snd_sf_zone * zp)336 set_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  */
347 static struct snd_sf_zone *
sf_zone_new(struct snd_sf_list * sflist,struct snd_soundfont * sf)348 sf_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  */
367 static void
set_sample_counter(struct snd_sf_list * sflist,struct snd_soundfont * sf,struct snd_sf_sample * sp)368 set_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  */
379 static struct snd_sf_sample *
sf_sample_new(struct snd_sf_list * sflist,struct snd_soundfont * sf)380 sf_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  */
398 static void
sf_sample_delete(struct snd_sf_list * sflist,struct snd_soundfont * sf,struct snd_sf_sample * sp)399 sf_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 */
411 static int
load_map(struct snd_sf_list * sflist,const void __user * data,int count)412 load_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 */
476 static int
remove_info(struct snd_sf_list * sflist,struct snd_soundfont * sf,int bank,int instr)477 remove_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  */
508 static int
load_info(struct snd_sf_list * sflist,const void __user * data,long count)509 load_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 */
600 static void
init_voice_info(struct soundfont_voice_info * avp)601 init_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  */
624 static void
init_voice_parm(struct soundfont_voice_parm * pp)625 init_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 */
646 static struct snd_sf_sample *
set_sample(struct snd_soundfont * sf,struct soundfont_voice_info * avp)647 set_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 */
672 static struct snd_sf_sample *
find_sample(struct snd_soundfont * sf,int sample_id)673 find_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  */
694 static int
load_data(struct snd_sf_list * sflist,const void __user * data,long count)695 load_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 */
754 static 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  */
784 int
snd_sf_linear_to_log(unsigned int amount,int offset,int ratio)785 snd_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 
804 EXPORT_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  */
819 static int
freq_to_note(int mhz)820 freq_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  */
832 static int
calc_rate_offset(int hz)833 calc_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 */
840 static int
calc_gus_envelope_time(int rate,int start,int end)841 calc_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) */
860 static const short attack_time_tbl[128] = {
861 32767, 32767, 5989, 4235, 2994, 2518, 2117, 1780, 1497, 1373, 1259, 1154, 1058, 970, 890, 816,
862 707, 691, 662, 634, 607, 581, 557, 533, 510, 489, 468, 448, 429, 411, 393, 377,
863 361, 345, 331, 317, 303, 290, 278, 266, 255, 244, 234, 224, 214, 205, 196, 188,
864 180, 172, 165, 158, 151, 145, 139, 133, 127, 122, 117, 112, 107, 102, 98, 94,
865 90, 86, 82, 79, 75, 72, 69, 66, 63, 61, 58, 56, 53, 51, 49, 47,
866 45, 43, 41, 39, 37, 36, 34, 33, 31, 30, 29, 28, 26, 25, 24, 23,
867 22, 21, 20, 19, 19, 18, 17, 16, 16, 15, 15, 14, 13, 13, 12, 12,
868 11, 11, 10, 10, 10, 9, 9, 8, 8, 8, 8, 7, 7, 7, 6, 0,
869 };
870 
871 static const short decay_time_tbl[128] = {
872 32767, 32767, 22614, 15990, 11307, 9508, 7995, 6723, 5653, 5184, 4754, 4359, 3997, 3665, 3361, 3082,
873 2828, 2765, 2648, 2535, 2428, 2325, 2226, 2132, 2042, 1955, 1872, 1793, 1717, 1644, 1574, 1507,
874 1443, 1382, 1324, 1267, 1214, 1162, 1113, 1066, 978, 936, 897, 859, 822, 787, 754, 722,
875 691, 662, 634, 607, 581, 557, 533, 510, 489, 468, 448, 429, 411, 393, 377, 361,
876 345, 331, 317, 303, 290, 278, 266, 255, 244, 234, 224, 214, 205, 196, 188, 180,
877 172, 165, 158, 151, 145, 139, 133, 127, 122, 117, 112, 107, 102, 98, 94, 90,
878 86, 82, 79, 75, 72, 69, 66, 63, 61, 58, 56, 53, 51, 49, 47, 45,
879 43, 41, 39, 37, 36, 34, 33, 31, 30, 29, 28, 26, 25, 24, 23, 22,
880 };
881 
882 /* delay time = 0x8000 - msec/92 */
883 int
snd_sf_calc_parm_hold(int msec)884 snd_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 */
893 static int
calc_parm_search(int msec,const short * table)894 calc_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 */
908 int
snd_sf_calc_parm_attack(int msec)909 snd_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 */
915 int
snd_sf_calc_parm_decay(int msec)916 snd_sf_calc_parm_decay(int msec)
917 {
918 	return calc_parm_search(msec, decay_time_tbl);
919 }
920 
921 int 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 */
937 static int
load_guspatch(struct snd_sf_list * sflist,const char __user * data,long count,int client)938 load_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 */
1115 int
snd_soundfont_load_guspatch(struct snd_sf_list * sflist,const char __user * data,long count,int client)1116 snd_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  */
1134 static void
rebuild_presets(struct snd_sf_list * sflist)1135 rebuild_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  */
1162 static void
add_preset(struct snd_sf_list * sflist,struct snd_sf_zone * cur)1163 add_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  */
1194 static void
delete_preset(struct snd_sf_list * sflist,struct snd_sf_zone * zp)1195 delete_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  */
1220 int
snd_soundfont_search_zone(struct snd_sf_list * sflist,int * notep,int vel,int preset,int bank,int def_preset,int def_bank,struct snd_sf_zone ** table,int max_layers)1221 snd_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  */
1254 static struct snd_sf_zone *
search_first_zone(struct snd_sf_list * sflist,int bank,int preset,int key)1255 search_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  */
1273 static int
search_zones(struct snd_sf_list * sflist,int * notep,int vel,int preset,int bank,struct snd_sf_zone ** table,int max_layers,int level)1274 search_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  */
1318 static int
get_index(int bank,int instr,int key)1319 get_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  */
1335 static void
snd_sf_init(struct snd_sf_list * sflist)1336 snd_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  */
1354 static void
snd_sf_clear(struct snd_sf_list * sflist)1355 snd_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  */
1384 struct snd_sf_list *
snd_sf_new(struct snd_sf_callback * callback,struct snd_util_memhdr * hdr)1385 snd_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  */
1407 void
snd_sf_free(struct snd_sf_list * sflist)1408 snd_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  */
1426 int
snd_soundfont_remove_samples(struct snd_sf_list * sflist)1427 snd_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  */
1442 int
snd_soundfont_remove_unlocked(struct snd_sf_list * sflist)1443 snd_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