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