Merge branch 'for-rmk' of git://git.marvell.com/orion
[sfrench/cifs-2.6.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(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
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
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 *
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
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
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
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
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 *
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
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 *
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
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
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
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
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
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
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 *
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 *
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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 *
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
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
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
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
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 *
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
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
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
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 }