~ubuntu-branches/ubuntu/precise/linux-lowlatency/precise

« back to all changes in this revision

Viewing changes to sound/synth/emux/soundfont.c

  • Committer: Package Import Robot
  • Author(s): Alessio Igor Bogani
  • Date: 2011-10-26 11:13:05 UTC
  • Revision ID: package-import@ubuntu.com-20111026111305-tz023xykf0i6eosh
Tags: upstream-3.2.0
ImportĀ upstreamĀ versionĀ 3.2.0

Show diffs side-by-side

added added

removed removed

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