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