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