linux/sound/synth/emux/soundfont.c
<<
>>
Prefs
   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 <linux/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
  37static int open_patch(struct snd_sf_list *sflist, const char __user *data,
  38                      int count, int client);
  39static struct snd_soundfont *newsf(struct snd_sf_list *sflist, int type, char *name);
  40static int is_identical_font(struct snd_soundfont *sf, int type, unsigned char *name);
  41static int close_patch(struct snd_sf_list *sflist);
  42static int probe_data(struct snd_sf_list *sflist, int sample_id);
  43static void set_zone_counter(struct snd_sf_list *sflist,
  44                             struct snd_soundfont *sf, struct snd_sf_zone *zp);
  45static struct snd_sf_zone *sf_zone_new(struct snd_sf_list *sflist,
  46                                       struct snd_soundfont *sf);
  47static void set_sample_counter(struct snd_sf_list *sflist,
  48                               struct snd_soundfont *sf, struct snd_sf_sample *sp);
  49static struct snd_sf_sample *sf_sample_new(struct snd_sf_list *sflist,
  50                                           struct snd_soundfont *sf);
  51static void sf_sample_delete(struct snd_sf_list *sflist,
  52                             struct snd_soundfont *sf, struct snd_sf_sample *sp);
  53static int load_map(struct snd_sf_list *sflist, const void __user *data, int count);
  54static int load_info(struct snd_sf_list *sflist, const void __user *data, long count);
  55static int remove_info(struct snd_sf_list *sflist, struct snd_soundfont *sf,
  56                       int bank, int instr);
  57static void init_voice_info(struct soundfont_voice_info *avp);
  58static void init_voice_parm(struct soundfont_voice_parm *pp);
  59static struct snd_sf_sample *set_sample(struct snd_soundfont *sf,
  60                                        struct soundfont_voice_info *avp);
  61static struct snd_sf_sample *find_sample(struct snd_soundfont *sf, int sample_id);
  62static int load_data(struct snd_sf_list *sflist, const void __user *data, long count);
  63static void rebuild_presets(struct snd_sf_list *sflist);
  64static void add_preset(struct snd_sf_list *sflist, struct snd_sf_zone *cur);
  65static void delete_preset(struct snd_sf_list *sflist, struct snd_sf_zone *zp);
  66static struct snd_sf_zone *search_first_zone(struct snd_sf_list *sflist,
  67                                             int bank, int preset, int key);
  68static 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);
  71static int get_index(int bank, int instr, int key);
  72static void snd_sf_init(struct snd_sf_list *sflist);
  73static void snd_sf_clear(struct snd_sf_list *sflist);
  74
  75/*
  76 * lock access to sflist
  77 */
  78static void
  79lock_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 */
  92static void
  93unlock_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 */
 106int
 107snd_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 */
 128int
 129snd_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) */
 221static inline int
 222is_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 */
 231static int
 232open_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 */
 269static struct snd_soundfont *
 270newsf(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 */
 304static int
 305is_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 */
 316static int
 317close_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 */
 333static int
 334probe_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 */
 348static void
 349set_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 */
 360static struct snd_sf_zone *
 361sf_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 */
 380static void
 381set_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 */
 392static struct snd_sf_sample *
 393sf_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 */
 411static void
 412sf_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 */
 424static int
 425load_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 */
 489static int
 490remove_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 */
 521static int
 522load_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 */
 613static void
 614init_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 */
 637static void
 638init_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 */
 659static struct snd_sf_sample *
 660set_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 */
 685static struct snd_sf_sample *
 686find_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 */
 707static int
 708load_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 */
 767static 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 */
 797int
 798snd_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
 817EXPORT_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 */
 832static int
 833freq_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 */
 845static int
 846calc_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 */
 853static int
 854calc_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) */
 871static short attack_time_tbl[128] = {
 87232767, 32767, 5989, 4235, 2994, 2518, 2117, 1780, 1497, 1373, 1259, 1154, 1058, 970, 890, 816,
 873707, 691, 662, 634, 607, 581, 557, 533, 510, 489, 468, 448, 429, 411, 393, 377,
 874361, 345, 331, 317, 303, 290, 278, 266, 255, 244, 234, 224, 214, 205, 196, 188,
 875180, 172, 165, 158, 151, 145, 139, 133, 127, 122, 117, 112, 107, 102, 98, 94,
 87690, 86, 82, 79, 75, 72, 69, 66, 63, 61, 58, 56, 53, 51, 49, 47,
 87745, 43, 41, 39, 37, 36, 34, 33, 31, 30, 29, 28, 26, 25, 24, 23,
 87822, 21, 20, 19, 19, 18, 17, 16, 16, 15, 15, 14, 13, 13, 12, 12,
 87911, 11, 10, 10, 10, 9, 9, 8, 8, 8, 8, 7, 7, 7, 6, 0,
 880};
 881
 882static short decay_time_tbl[128] = {
 88332767, 32767, 22614, 15990, 11307, 9508, 7995, 6723, 5653, 5184, 4754, 4359, 3997, 3665, 3361, 3082,
 8842828, 2765, 2648, 2535, 2428, 2325, 2226, 2132, 2042, 1955, 1872, 1793, 1717, 1644, 1574, 1507,
 8851443, 1382, 1324, 1267, 1214, 1162, 1113, 1066, 978, 936, 897, 859, 822, 787, 754, 722,
 886691, 662, 634, 607, 581, 557, 533, 510, 489, 468, 448, 429, 411, 393, 377, 361,
 887345, 331, 317, 303, 290, 278, 266, 255, 244, 234, 224, 214, 205, 196, 188, 180,
 888172, 165, 158, 151, 145, 139, 133, 127, 122, 117, 112, 107, 102, 98, 94, 90,
 88986, 82, 79, 75, 72, 69, 66, 63, 61, 58, 56, 53, 51, 49, 47, 45,
 89043, 41, 39, 37, 36, 34, 33, 31, 30, 29, 28, 26, 25, 24, 23, 22,
 891};
 892
 893/* delay time = 0x8000 - msec/92 */
 894int
 895snd_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 */
 904static int
 905calc_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 */
 919int
 920snd_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 */
 926int
 927snd_sf_calc_parm_decay(int msec)
 928{
 929        return calc_parm_search(msec, decay_time_tbl);
 930}
 931
 932int 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 */
 948static int
 949load_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                        kfree(zone);
1025                        return rc;
1026                }
1027                /* memory offset is updated after */
1028        }
1029
1030        /* update the memory offset here */
1031        sflist->mem_used += smp->v.truesize;
1032
1033        zone->v.sample = sample_id; /* the last sample */
1034        zone->v.rate_offset = calc_rate_offset(patch.base_freq);
1035        note = freq_to_note(patch.base_note);
1036        zone->v.root = note / 100;
1037        zone->v.tune = -(note % 100);
1038        zone->v.low = (freq_to_note(patch.low_note) + 99) / 100;
1039        zone->v.high = freq_to_note(patch.high_note) / 100;
1040        /* panning position; -128 - 127 => 0-127 */
1041        zone->v.pan = (patch.panning + 128) / 2;
1042#if 0
1043        snd_printk(KERN_DEBUG
1044                   "gus: basefrq=%d (ofs=%d) root=%d,tune=%d, range:%d-%d\n",
1045                   (int)patch.base_freq, zone->v.rate_offset,
1046                   zone->v.root, zone->v.tune, zone->v.low, zone->v.high);
1047#endif
1048
1049        /* detuning is ignored */
1050        /* 6points volume envelope */
1051        if (patch.mode & WAVE_ENVELOPES) {
1052                int attack, hold, decay, release;
1053                attack = calc_gus_envelope_time
1054                        (patch.env_rate[0], 0, patch.env_offset[0]);
1055                hold = calc_gus_envelope_time
1056                        (patch.env_rate[1], patch.env_offset[0],
1057                         patch.env_offset[1]);
1058                decay = calc_gus_envelope_time
1059                        (patch.env_rate[2], patch.env_offset[1],
1060                         patch.env_offset[2]);
1061                release = calc_gus_envelope_time
1062                        (patch.env_rate[3], patch.env_offset[1],
1063                         patch.env_offset[4]);
1064                release += calc_gus_envelope_time
1065                        (patch.env_rate[4], patch.env_offset[3],
1066                         patch.env_offset[4]);
1067                release += calc_gus_envelope_time
1068                        (patch.env_rate[5], patch.env_offset[4],
1069                         patch.env_offset[5]);
1070                zone->v.parm.volatkhld = 
1071                        (snd_sf_calc_parm_hold(hold) << 8) |
1072                        snd_sf_calc_parm_attack(attack);
1073                zone->v.parm.voldcysus = (calc_gus_sustain(patch.env_offset[2]) << 8) |
1074                        snd_sf_calc_parm_decay(decay);
1075                zone->v.parm.volrelease = 0x8000 | snd_sf_calc_parm_decay(release);
1076                zone->v.attenuation = calc_gus_attenuation(patch.env_offset[0]);
1077#if 0
1078                snd_printk(KERN_DEBUG
1079                           "gus: atkhld=%x, dcysus=%x, volrel=%x, att=%d\n",
1080                           zone->v.parm.volatkhld,
1081                           zone->v.parm.voldcysus,
1082                           zone->v.parm.volrelease,
1083                           zone->v.attenuation);
1084#endif
1085        }
1086
1087        /* fast release */
1088        if (patch.mode & WAVE_FAST_RELEASE) {
1089                zone->v.parm.volrelease = 0x807f;
1090        }
1091
1092        /* tremolo effect */
1093        if (patch.mode & WAVE_TREMOLO) {
1094                int rate = (patch.tremolo_rate * 1000 / 38) / 42;
1095                zone->v.parm.tremfrq = ((patch.tremolo_depth / 2) << 8) | rate;
1096        }
1097        /* vibrato effect */
1098        if (patch.mode & WAVE_VIBRATO) {
1099                int rate = (patch.vibrato_rate * 1000 / 38) / 42;
1100                zone->v.parm.fm2frq2 = ((patch.vibrato_depth / 6) << 8) | rate;
1101        }
1102        
1103        /* scale_freq, scale_factor, volume, and fractions not implemented */
1104
1105        if (!(smp->v.mode_flags & SNDRV_SFNT_SAMPLE_SINGLESHOT))
1106                zone->v.mode = SNDRV_SFNT_MODE_LOOPING;
1107        else
1108                zone->v.mode = 0;
1109
1110        /* append to the tail of the list */
1111        /*zone->bank = ctrls[AWE_MD_GUS_BANK];*/
1112        zone->bank = 0;
1113        zone->instr = patch.instr_no;
1114        zone->mapped = 0;
1115        zone->v.sf_id = sf->id;
1116
1117        zone->sample = set_sample(sf, &zone->v);
1118
1119        /* rebuild preset now */
1120        add_preset(sflist, zone);
1121
1122        return 0;
1123}
1124
1125/* load GUS patch */
1126int
1127snd_soundfont_load_guspatch(struct snd_sf_list *sflist, const char __user *data,
1128                            long count, int client)
1129{
1130        int rc;
1131        lock_preset(sflist);
1132        rc = load_guspatch(sflist, data, count, client);
1133        unlock_preset(sflist);
1134        return rc;
1135}
1136
1137
1138/*
1139 * Rebuild the preset table.  This is like a hash table in that it allows
1140 * quick access to the zone information.  For each preset there are zone
1141 * structures linked by next_instr and by next_zone.  Former is the whole
1142 * link for this preset, and latter is the link for zone (i.e. instrument/
1143 * bank/key combination).
1144 */
1145static void
1146rebuild_presets(struct snd_sf_list *sflist)
1147{
1148        struct snd_soundfont *sf;
1149        struct snd_sf_zone *cur;
1150
1151        /* clear preset table */
1152        memset(sflist->presets, 0, sizeof(sflist->presets));
1153
1154        /* search all fonts and insert each font */
1155        for (sf = sflist->fonts; sf; sf = sf->next) {
1156                for (cur = sf->zones; cur; cur = cur->next) {
1157                        if (! cur->mapped && cur->sample == NULL) {
1158                                /* try again to search the corresponding sample */
1159                                cur->sample = set_sample(sf, &cur->v);
1160                                if (cur->sample == NULL)
1161                                        continue;
1162                        }
1163
1164                        add_preset(sflist, cur);
1165                }
1166        }
1167}
1168
1169
1170/*
1171 * add the given zone to preset table
1172 */
1173static void
1174add_preset(struct snd_sf_list *sflist, struct snd_sf_zone *cur)
1175{
1176        struct snd_sf_zone *zone;
1177        int index;
1178
1179        zone = search_first_zone(sflist, cur->bank, cur->instr, cur->v.low);
1180        if (zone && zone->v.sf_id != cur->v.sf_id) {
1181                /* different instrument was already defined */
1182                struct snd_sf_zone *p;
1183                /* compare the allocated time */
1184                for (p = zone; p; p = p->next_zone) {
1185                        if (p->counter > cur->counter)
1186                                /* the current is older.. skipped */
1187                                return;
1188                }
1189                /* remove old zones */
1190                delete_preset(sflist, zone);
1191                zone = NULL; /* do not forget to clear this! */
1192        }
1193
1194        /* prepend this zone */
1195        if ((index = get_index(cur->bank, cur->instr, cur->v.low)) < 0)
1196                return;
1197        cur->next_zone = zone; /* zone link */
1198        cur->next_instr = sflist->presets[index]; /* preset table link */
1199        sflist->presets[index] = cur;
1200}
1201
1202/*
1203 * delete the given zones from preset_table
1204 */
1205static void
1206delete_preset(struct snd_sf_list *sflist, struct snd_sf_zone *zp)
1207{
1208        int index;
1209        struct snd_sf_zone *p;
1210
1211        if ((index = get_index(zp->bank, zp->instr, zp->v.low)) < 0)
1212                return;
1213        for (p = sflist->presets[index]; p; p = p->next_instr) {
1214                while (p->next_instr == zp) {
1215                        p->next_instr = zp->next_instr;
1216                        zp = zp->next_zone;
1217                        if (zp == NULL)
1218                                return;
1219                }
1220        }
1221}
1222
1223
1224/*
1225 * Search matching zones from preset table.
1226 * The note can be rewritten by preset mapping (alias).
1227 * The found zones are stored on 'table' array.  max_layers defines
1228 * the maximum number of elements in this array.
1229 * This function returns the number of found zones.  0 if not found.
1230 */
1231int
1232snd_soundfont_search_zone(struct snd_sf_list *sflist, int *notep, int vel,
1233                          int preset, int bank,
1234                          int def_preset, int def_bank,
1235                          struct snd_sf_zone **table, int max_layers)
1236{
1237        int nvoices;
1238        unsigned long flags;
1239
1240        /* this function is supposed to be called atomically,
1241         * so we check the lock.  if it's busy, just returns 0 to
1242         * tell the caller the busy state
1243         */
1244        spin_lock_irqsave(&sflist->lock, flags);
1245        if (sflist->presets_locked) {
1246                spin_unlock_irqrestore(&sflist->lock, flags);
1247                return 0;
1248        }
1249        nvoices = search_zones(sflist, notep, vel, preset, bank,
1250                               table, max_layers, 0);
1251        if (! nvoices) {
1252                if (preset != def_preset || bank != def_bank)
1253                        nvoices = search_zones(sflist, notep, vel,
1254                                               def_preset, def_bank,
1255                                               table, max_layers, 0);
1256        }
1257        spin_unlock_irqrestore(&sflist->lock, flags);
1258        return nvoices;
1259}
1260
1261
1262/*
1263 * search the first matching zone
1264 */
1265static struct snd_sf_zone *
1266search_first_zone(struct snd_sf_list *sflist, int bank, int preset, int key)
1267{
1268        int index;
1269        struct snd_sf_zone *zp;
1270
1271        if ((index = get_index(bank, preset, key)) < 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        if ((sflist = kzalloc(sizeof(*sflist), GFP_KERNEL)) == NULL)
1401                return NULL;
1402
1403        mutex_init(&sflist->presets_mutex);
1404        spin_lock_init(&sflist->lock);
1405        sflist->memhdr = hdr;
1406
1407        if (callback)
1408                sflist->callback = *callback;
1409
1410        snd_sf_init(sflist);
1411        return sflist;
1412}
1413
1414
1415/*
1416 * Free everything allocated off the sflist structure.
1417 */
1418void
1419snd_sf_free(struct snd_sf_list *sflist)
1420{
1421        if (sflist == NULL)
1422                return;
1423        
1424        lock_preset(sflist);
1425        if (sflist->callback.sample_reset)
1426                sflist->callback.sample_reset(sflist->callback.private_data);
1427        snd_sf_clear(sflist);
1428        unlock_preset(sflist);
1429
1430        kfree(sflist);
1431}
1432
1433/*
1434 * Remove all samples
1435 * The soundcard should be silet before calling this function.
1436 */
1437int
1438snd_soundfont_remove_samples(struct snd_sf_list *sflist)
1439{
1440        lock_preset(sflist);
1441        if (sflist->callback.sample_reset)
1442                sflist->callback.sample_reset(sflist->callback.private_data);
1443        snd_sf_clear(sflist);
1444        unlock_preset(sflist);
1445
1446        return 0;
1447}
1448
1449/*
1450 * Remove unlocked samples.
1451 * The soundcard should be silent before calling this function.
1452 */
1453int
1454snd_soundfont_remove_unlocked(struct snd_sf_list *sflist)
1455{
1456        struct snd_soundfont *sf;
1457        struct snd_sf_zone *zp, *nextzp;
1458        struct snd_sf_sample *sp, *nextsp;
1459
1460        lock_preset(sflist);
1461
1462        if (sflist->callback.sample_reset)
1463                sflist->callback.sample_reset(sflist->callback.private_data);
1464
1465        /* to be sure */
1466        memset(sflist->presets, 0, sizeof(sflist->presets));
1467
1468        for (sf = sflist->fonts; sf; sf = sf->next) {
1469                for (zp = sf->zones; zp; zp = nextzp) {
1470                        if (zp->counter < sflist->zone_locked)
1471                                break;
1472                        nextzp = zp->next;
1473                        sf->zones = nextzp;
1474                        kfree(zp);
1475                }
1476
1477                for (sp = sf->samples; sp; sp = nextsp) {
1478                        if (sp->counter < sflist->sample_locked)
1479                                break;
1480                        nextsp = sp->next;
1481                        sf->samples = nextsp;
1482                        sflist->mem_used -= sp->v.truesize;
1483                        if (sflist->callback.sample_free)
1484                                sflist->callback.sample_free(sflist->callback.private_data,
1485                                                             sp, sflist->memhdr);
1486                        kfree(sp);
1487                }
1488        }
1489
1490        sflist->zone_counter = sflist->zone_locked;
1491        sflist->sample_counter = sflist->sample_locked;
1492
1493        rebuild_presets(sflist);
1494
1495        unlock_preset(sflist);
1496        return 0;
1497}
1498