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