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