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 <asm/uaccess.h>
  29#include <linux/slab.h>
  30#include <linux/export.h>
  31#include <sound/core.h>
  32#include <sound/soundfont.h>
  33#include <sound/seq_oss_legacy.h>
  34
  35/* Prototypes for static functions */
  36
  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                        return rc;
1025                }
1026                /* memory offset is updated after */
1027        }
1028
1029        /* update the memory offset here */
1030        sflist->mem_used += smp->v.truesize;
1031
1032        zone->v.sample = sample_id; /* the last sample */
1033        zone->v.rate_offset = calc_rate_offset(patch.base_freq);
1034        note = freq_to_note(patch.base_note);
1035        zone->v.root = note / 100;
1036        zone->v.tune = -(note % 100);
1037        zone->v.low = (freq_to_note(patch.low_note) + 99) / 100;
1038        zone->v.high = freq_to_note(patch.high_note) / 100;
1039        /* panning position; -128 - 127 => 0-127 */
1040        zone->v.pan = (patch.panning + 128) / 2;
1041#if 0
1042        snd_printk(KERN_DEBUG
1043                   "gus: basefrq=%d (ofs=%d) root=%d,tune=%d, range:%d-%d\n",
1044                   (int)patch.base_freq, zone->v.rate_offset,
1045                   zone->v.root, zone->v.tune, zone->v.low, zone->v.high);
1046#endif
1047
1048        /* detuning is ignored */
1049        /* 6points volume envelope */
1050        if (patch.mode & WAVE_ENVELOPES) {
1051                int attack, hold, decay, release;
1052                attack = calc_gus_envelope_time
1053                        (patch.env_rate[0], 0, patch.env_offset[0]);
1054                hold = calc_gus_envelope_time
1055                        (patch.env_rate[1], patch.env_offset[0],
1056                         patch.env_offset[1]);
1057                decay = calc_gus_envelope_time
1058                        (patch.env_rate[2], patch.env_offset[1],
1059                         patch.env_offset[2]);
1060                release = calc_gus_envelope_time
1061                        (patch.env_rate[3], patch.env_offset[1],
1062                         patch.env_offset[4]);
1063                release += calc_gus_envelope_time
1064                        (patch.env_rate[4], patch.env_offset[3],
1065                         patch.env_offset[4]);
1066                release += calc_gus_envelope_time
1067                        (patch.env_rate[5], patch.env_offset[4],
1068                         patch.env_offset[5]);
1069                zone->v.parm.volatkhld = 
1070                        (snd_sf_calc_parm_hold(hold) << 8) |
1071                        snd_sf_calc_parm_attack(attack);
1072                zone->v.parm.voldcysus = (calc_gus_sustain(patch.env_offset[2]) << 8) |
1073                        snd_sf_calc_parm_decay(decay);
1074                zone->v.parm.volrelease = 0x8000 | snd_sf_calc_parm_decay(release);
1075                zone->v.attenuation = calc_gus_attenuation(patch.env_offset[0]);
1076#if 0
1077                snd_printk(KERN_DEBUG
1078                           "gus: atkhld=%x, dcysus=%x, volrel=%x, att=%d\n",
1079                           zone->v.parm.volatkhld,
1080                           zone->v.parm.voldcysus,
1081                           zone->v.parm.volrelease,
1082                           zone->v.attenuation);
1083#endif
1084        }
1085
1086        /* fast release */
1087        if (patch.mode & WAVE_FAST_RELEASE) {
1088                zone->v.parm.volrelease = 0x807f;
1089        }
1090
1091        /* tremolo effect */
1092        if (patch.mode & WAVE_TREMOLO) {
1093                int rate = (patch.tremolo_rate * 1000 / 38) / 42;
1094                zone->v.parm.tremfrq = ((patch.tremolo_depth / 2) << 8) | rate;
1095        }
1096        /* vibrato effect */
1097        if (patch.mode & WAVE_VIBRATO) {
1098                int rate = (patch.vibrato_rate * 1000 / 38) / 42;
1099                zone->v.parm.fm2frq2 = ((patch.vibrato_depth / 6) << 8) | rate;
1100        }
1101        
1102        /* scale_freq, scale_factor, volume, and fractions not implemented */
1103
1104        if (!(smp->v.mode_flags & SNDRV_SFNT_SAMPLE_SINGLESHOT))
1105                zone->v.mode = SNDRV_SFNT_MODE_LOOPING;
1106        else
1107                zone->v.mode = 0;
1108
1109        /* append to the tail of the list */
1110        /*zone->bank = ctrls[AWE_MD_GUS_BANK];*/
1111        zone->bank = 0;
1112        zone->instr = patch.instr_no;
1113        zone->mapped = 0;
1114        zone->v.sf_id = sf->id;
1115
1116        zone->sample = set_sample(sf, &zone->v);
1117
1118        /* rebuild preset now */
1119        add_preset(sflist, zone);
1120
1121        return 0;
1122}
1123
1124/* load GUS patch */
1125int
1126snd_soundfont_load_guspatch(struct snd_sf_list *sflist, const char __user *data,
1127                            long count, int client)
1128{
1129        int rc;
1130        lock_preset(sflist);
1131        rc = load_guspatch(sflist, data, count, client);
1132        unlock_preset(sflist);
1133        return rc;
1134}
1135
1136
1137/*
1138 * Rebuild the preset table.  This is like a hash table in that it allows
1139 * quick access to the zone information.  For each preset there are zone
1140 * structures linked by next_instr and by next_zone.  Former is the whole
1141 * link for this preset, and latter is the link for zone (i.e. instrument/
1142 * bank/key combination).
1143 */
1144static void
1145rebuild_presets(struct snd_sf_list *sflist)
1146{
1147        struct snd_soundfont *sf;
1148        struct snd_sf_zone *cur;
1149
1150        /* clear preset table */
1151        memset(sflist->presets, 0, sizeof(sflist->presets));
1152
1153        /* search all fonts and insert each font */
1154        for (sf = sflist->fonts; sf; sf = sf->next) {
1155                for (cur = sf->zones; cur; cur = cur->next) {
1156                        if (! cur->mapped && cur->sample == NULL) {
1157                                /* try again to search the corresponding sample */
1158                                cur->sample = set_sample(sf, &cur->v);
1159                                if (cur->sample == NULL)
1160                                        continue;
1161                        }
1162
1163                        add_preset(sflist, cur);
1164                }
1165        }
1166}
1167
1168
1169/*
1170 * add the given zone to preset table
1171 */
1172static void
1173add_preset(struct snd_sf_list *sflist, struct snd_sf_zone *cur)
1174{
1175        struct snd_sf_zone *zone;
1176        int index;
1177
1178        zone = search_first_zone(sflist, cur->bank, cur->instr, cur->v.low);
1179        if (zone && zone->v.sf_id != cur->v.sf_id) {
1180                /* different instrument was already defined */
1181                struct snd_sf_zone *p;
1182                /* compare the allocated time */
1183                for (p = zone; p; p = p->next_zone) {
1184                        if (p->counter > cur->counter)
1185                                /* the current is older.. skipped */
1186                                return;
1187                }
1188                /* remove old zones */
1189                delete_preset(sflist, zone);
1190                zone = NULL; /* do not forget to clear this! */
1191        }
1192
1193        /* prepend this zone */
1194        if ((index = get_index(cur->bank, cur->instr, cur->v.low)) < 0)
1195                return;
1196        cur->next_zone = zone; /* zone link */
1197        cur->next_instr = sflist->presets[index]; /* preset table link */
1198        sflist->presets[index] = cur;
1199}
1200
1201/*
1202 * delete the given zones from preset_table
1203 */
1204static void
1205delete_preset(struct snd_sf_list *sflist, struct snd_sf_zone *zp)
1206{
1207        int index;
1208        struct snd_sf_zone *p;
1209
1210        if ((index = get_index(zp->bank, zp->instr, zp->v.low)) < 0)
1211                return;
1212        for (p = sflist->presets[index]; p; p = p->next_instr) {
1213                while (p->next_instr == zp) {
1214                        p->next_instr = zp->next_instr;
1215                        zp = zp->next_zone;
1216                        if (zp == NULL)
1217                                return;
1218                }
1219        }
1220}
1221
1222
1223/*
1224 * Search matching zones from preset table.
1225 * The note can be rewritten by preset mapping (alias).
1226 * The found zones are stored on 'table' array.  max_layers defines
1227 * the maximum number of elements in this array.
1228 * This function returns the number of found zones.  0 if not found.
1229 */
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        if ((index = get_index(bank, preset, key)) < 0)
1271                return NULL;
1272        for (zp = sflist->presets[index]; zp; zp = zp->next_instr) {
1273                if (zp->instr == preset && zp->bank == bank)
1274                        return zp;
1275        }
1276        return NULL;
1277}
1278
1279
1280/*
1281 * search matching zones from sflist.  can be called recursively.
1282 */
1283static int
1284search_zones(struct snd_sf_list *sflist, int *notep, int vel,
1285             int preset, int bank, struct snd_sf_zone **table,
1286             int max_layers, int level)
1287{
1288        struct snd_sf_zone *zp;
1289        int nvoices;
1290
1291        zp = search_first_zone(sflist, bank, preset, *notep);
1292        nvoices = 0;
1293        for (; zp; zp = zp->next_zone) {
1294                if (*notep >= zp->v.low && *notep <= zp->v.high &&
1295                    vel >= zp->v.vellow && vel <= zp->v.velhigh) {
1296                        if (zp->mapped) {
1297                                /* search preset mapping (aliasing) */
1298                                int key = zp->v.fixkey;
1299                                preset = zp->v.start;
1300                                bank = zp->v.end;
1301
1302                                if (level > 5) /* too deep alias level */
1303                                        return 0;
1304                                if (key < 0)
1305                                        key = *notep;
1306                                nvoices = search_zones(sflist, &key, vel,
1307                                                       preset, bank, table,
1308                                                       max_layers, level + 1);
1309                                if (nvoices > 0)
1310                                        *notep = key;
1311                                break;
1312                        }
1313                        table[nvoices++] = zp;
1314                        if (nvoices >= max_layers)
1315                                break;
1316                }
1317        }
1318
1319        return nvoices;
1320}
1321
1322
1323/* calculate the index of preset table:
1324 * drums are mapped from 128 to 255 according to its note key.
1325 * other instruments are mapped from 0 to 127.
1326 * if the index is out of range, return -1.
1327 */
1328static int
1329get_index(int bank, int instr, int key)
1330{
1331        int index;
1332        if (SF_IS_DRUM_BANK(bank))
1333                index = key + SF_MAX_INSTRUMENTS;
1334        else
1335                index = instr;
1336        index = index % SF_MAX_PRESETS;
1337        if (index < 0)
1338                return -1;
1339        return index;
1340}
1341
1342/*
1343 * Initialise the sflist structure.
1344 */
1345static void
1346snd_sf_init(struct snd_sf_list *sflist)
1347{
1348        memset(sflist->presets, 0, sizeof(sflist->presets));
1349
1350        sflist->mem_used = 0;
1351        sflist->currsf = NULL;
1352        sflist->open_client = -1;
1353        sflist->fonts = NULL;
1354        sflist->fonts_size = 0;
1355        sflist->zone_counter = 0;
1356        sflist->sample_counter = 0;
1357        sflist->zone_locked = 0;
1358        sflist->sample_locked = 0;
1359}
1360
1361/*
1362 * Release all list records
1363 */
1364static void
1365snd_sf_clear(struct snd_sf_list *sflist)
1366{
1367        struct snd_soundfont *sf, *nextsf;
1368        struct snd_sf_zone *zp, *nextzp;
1369        struct snd_sf_sample *sp, *nextsp;
1370
1371        for (sf = sflist->fonts; sf; sf = nextsf) {
1372                nextsf = sf->next;
1373                for (zp = sf->zones; zp; zp = nextzp) {
1374                        nextzp = zp->next;
1375                        kfree(zp);
1376                }
1377                for (sp = sf->samples; sp; sp = nextsp) {
1378                        nextsp = sp->next;
1379                        if (sflist->callback.sample_free)
1380                                sflist->callback.sample_free(sflist->callback.private_data,
1381                                                             sp, sflist->memhdr);
1382                        kfree(sp);
1383                }
1384                kfree(sf);
1385        }
1386
1387        snd_sf_init(sflist);
1388}
1389
1390
1391/*
1392 * Create a new sflist structure
1393 */
1394struct snd_sf_list *
1395snd_sf_new(struct snd_sf_callback *callback, struct snd_util_memhdr *hdr)
1396{
1397        struct snd_sf_list *sflist;
1398
1399        if ((sflist = kzalloc(sizeof(*sflist), GFP_KERNEL)) == NULL)
1400                return NULL;
1401
1402        mutex_init(&sflist->presets_mutex);
1403        spin_lock_init(&sflist->lock);
1404        sflist->memhdr = hdr;
1405
1406        if (callback)
1407                sflist->callback = *callback;
1408
1409        snd_sf_init(sflist);
1410        return sflist;
1411}
1412
1413
1414/*
1415 * Free everything allocated off the sflist structure.
1416 */
1417void
1418snd_sf_free(struct snd_sf_list *sflist)
1419{
1420        if (sflist == NULL)
1421                return;
1422        
1423        lock_preset(sflist);
1424        if (sflist->callback.sample_reset)
1425                sflist->callback.sample_reset(sflist->callback.private_data);
1426        snd_sf_clear(sflist);
1427        unlock_preset(sflist);
1428
1429        kfree(sflist);
1430}
1431
1432/*
1433 * Remove all samples
1434 * The soundcard should be silet before calling this function.
1435 */
1436int
1437snd_soundfont_remove_samples(struct snd_sf_list *sflist)
1438{
1439        lock_preset(sflist);
1440        if (sflist->callback.sample_reset)
1441                sflist->callback.sample_reset(sflist->callback.private_data);
1442        snd_sf_clear(sflist);
1443        unlock_preset(sflist);
1444
1445        return 0;
1446}
1447
1448/*
1449 * Remove unlocked samples.
1450 * The soundcard should be silent before calling this function.
1451 */
1452int
1453snd_soundfont_remove_unlocked(struct snd_sf_list *sflist)
1454{
1455        struct snd_soundfont *sf;
1456        struct snd_sf_zone *zp, *nextzp;
1457        struct snd_sf_sample *sp, *nextsp;
1458
1459        lock_preset(sflist);
1460
1461        if (sflist->callback.sample_reset)
1462                sflist->callback.sample_reset(sflist->callback.private_data);
1463
1464        /* to be sure */
1465        memset(sflist->presets, 0, sizeof(sflist->presets));
1466
1467        for (sf = sflist->fonts; sf; sf = sf->next) {
1468                for (zp = sf->zones; zp; zp = nextzp) {
1469                        if (zp->counter < sflist->zone_locked)
1470                                break;
1471                        nextzp = zp->next;
1472                        sf->zones = nextzp;
1473                        kfree(zp);
1474                }
1475
1476                for (sp = sf->samples; sp; sp = nextsp) {
1477                        if (sp->counter < sflist->sample_locked)
1478                                break;
1479                        nextsp = sp->next;
1480                        sf->samples = nextsp;
1481                        sflist->mem_used -= sp->v.truesize;
1482                        if (sflist->callback.sample_free)
1483                                sflist->callback.sample_free(sflist->callback.private_data,
1484                                                             sp, sflist->memhdr);
1485                        kfree(sp);
1486                }
1487        }
1488
1489        sflist->zone_counter = sflist->zone_locked;
1490        sflist->sample_counter = sflist->sample_locked;
1491
1492        rebuild_presets(sflist);
1493
1494        unlock_preset(sflist);
1495        return 0;
1496}
1497