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