Ignore:
Timestamp:
Dec 11, 2005, 5:57:39 PM (20 years ago)
Author:
vladest
Message:

Latest update from ALSA. some intial > 15 interrupts support

Location:
GPL/trunk/alsa-kernel/synth
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • GPL/trunk/alsa-kernel/synth/emux/emux.c

    r33 r34  
    2323#include <linux/sched.h>
    2424#include <linux/slab.h>
     25#include <linux/string.h>
    2526#include <sound/core.h>
    2627#include <sound/emux_synth.h>
     
    3536 * create a new hardware dependent device for Emu8000/Emu10k1
    3637 */
    37 int snd_emux_new(snd_emux_t **remu)
    38 {
    39     snd_emux_t *emu;
    40 
    41     *remu = NULL;
    42     emu = kcalloc(1, sizeof(*emu), GFP_KERNEL);
    43     if (emu == NULL)
    44         return -ENOMEM;
    45 
    46     spin_lock_init(&emu->voice_lock);
    47     init_MUTEX(&emu->register_mutex);
    48 
    49     emu->client = -1;
    50 #ifdef CONFIG_SND_OSSEMUL
    51     emu->oss_synth = NULL;
    52 #endif
    53     emu->max_voices = 0;
    54     emu->use_time = 0;
    55 
    56     emu->tlist.function = snd_emux_timer_callback;
    57     emu->tlist.data = (unsigned long)emu;
    58     emu->timer_active = 0;
    59 
    60     *remu = emu;
    61     return 0;
    62 }
    63 
    64 
    65 /*
    66  */
    67 int snd_emux_register(snd_emux_t *emu, snd_card_t *card, int index, char *name)
    68 {
    69     snd_sf_callback_t sf_cb;
    70 
    71     snd_assert(emu->hw != NULL, return -EINVAL);
    72     snd_assert(emu->max_voices > 0, return -EINVAL);
    73     snd_assert(card != NULL, return -EINVAL);
    74     snd_assert(name != NULL, return -EINVAL);
    75 
    76     emu->card = card;
    77     emu->name = snd_kmalloc_strdup(name, GFP_KERNEL);
    78     emu->voices = kcalloc(emu->max_voices, sizeof(snd_emux_voice_t), GFP_KERNEL);
    79     if (emu->voices == NULL)
    80         return -ENOMEM;
    81 
    82     /* create soundfont list */
    83     memset(&sf_cb, 0, sizeof(sf_cb));
    84     sf_cb.private_data = emu;
    85     sf_cb.sample_new = (snd_sf_sample_new_t)emu->ops.sample_new;
    86     sf_cb.sample_free = (snd_sf_sample_free_t)emu->ops.sample_free;
    87     sf_cb.sample_reset = (snd_sf_sample_reset_t)emu->ops.sample_reset;
    88     emu->sflist = snd_sf_new(&sf_cb, emu->memhdr);
    89     if (emu->sflist == NULL)
    90         return -ENOMEM;
    91 
    92     snd_emux_init_voices(emu);
    93 
    94     snd_emux_init_seq(emu, card, index);
    95 #ifdef CONFIG_SND_OSSEMUL
    96     snd_emux_init_seq_oss(emu);
    97 #endif
    98     snd_emux_init_virmidi(emu, card);
     38int snd_emux_new(struct snd_emux **remu)
     39{
     40        struct snd_emux *emu;
     41
     42        *remu = NULL;
     43        emu = kzalloc(sizeof(*emu), GFP_KERNEL);
     44        if (emu == NULL)
     45                return -ENOMEM;
     46
     47        spin_lock_init(&emu->voice_lock);
     48        init_MUTEX(&emu->register_mutex);
     49
     50        emu->client = -1;
     51#ifdef CONFIG_SND_SEQUENCER_OSS
     52        emu->oss_synth = NULL;
     53#endif
     54        emu->max_voices = 0;
     55        emu->use_time = 0;
     56
     57        init_timer(&emu->tlist);
     58        emu->tlist.function = snd_emux_timer_callback;
     59        emu->tlist.data = (unsigned long)emu;
     60        emu->timer_active = 0;
     61
     62        *remu = emu;
     63        return 0;
     64}
     65
     66
     67/*
     68 */
     69static int sf_sample_new(void *private_data, struct snd_sf_sample *sp,
     70                                  struct snd_util_memhdr *hdr,
     71                                  const void __user *buf, long count)
     72{
     73        struct snd_emux *emu = private_data;
     74        return emu->ops.sample_new(emu, sp, hdr, buf, count);
     75       
     76}
     77
     78static int sf_sample_free(void *private_data, struct snd_sf_sample *sp,
     79                                   struct snd_util_memhdr *hdr)
     80{
     81        struct snd_emux *emu = private_data;
     82        return emu->ops.sample_free(emu, sp, hdr);
     83       
     84}
     85
     86static void sf_sample_reset(void *private_data)
     87{
     88        struct snd_emux *emu = private_data;
     89        emu->ops.sample_reset(emu);
     90}
     91
     92int snd_emux_register(struct snd_emux *emu, struct snd_card *card, int index, char *name)
     93{
     94        int err;
     95        struct snd_sf_callback sf_cb;
     96
     97        snd_assert(emu->hw != NULL, return -EINVAL);
     98        snd_assert(emu->max_voices > 0, return -EINVAL);
     99        snd_assert(card != NULL, return -EINVAL);
     100        snd_assert(name != NULL, return -EINVAL);
     101
     102        emu->card = card;
     103        emu->name = kstrdup(name, GFP_KERNEL);
     104        emu->voices = kcalloc(emu->max_voices, sizeof(struct snd_emux_voice),
     105                              GFP_KERNEL);
     106        if (emu->voices == NULL)
     107                return -ENOMEM;
     108
     109        /* create soundfont list */
     110        memset(&sf_cb, 0, sizeof(sf_cb));
     111        sf_cb.private_data = emu;
     112        if (emu->ops.sample_new)
     113                sf_cb.sample_new = sf_sample_new;
     114        if (emu->ops.sample_free)
     115                sf_cb.sample_free = sf_sample_free;
     116        if (emu->ops.sample_reset)
     117                sf_cb.sample_reset = sf_sample_reset;
     118        emu->sflist = snd_sf_new(&sf_cb, emu->memhdr);
     119        if (emu->sflist == NULL)
     120                return -ENOMEM;
     121
     122        if ((err = snd_emux_init_hwdep(emu)) < 0)
     123                return err;
     124
     125        snd_emux_init_voices(emu);
     126
     127        snd_emux_init_seq(emu, card, index);
     128#ifdef CONFIG_SND_SEQUENCER_OSS
     129        snd_emux_init_seq_oss(emu);
     130#endif
     131        snd_emux_init_virmidi(emu, card);
    99132
    100133#ifdef CONFIG_PROC_FS
    101     snd_emux_proc_init(emu, card, index);
    102 #endif
    103     return 0;
    104 }
    105 
    106 
    107 /*
    108  */
    109 int snd_emux_free(snd_emux_t *emu)
    110 {
    111     unsigned long flags;
    112 
    113     if (! emu)
    114         return -EINVAL;
    115 
    116     spin_lock_irqsave(&emu->voice_lock, flags);
    117     if (emu->timer_active)
    118         del_timer(&emu->tlist);
    119     spin_unlock_irqrestore(&emu->voice_lock, flags);
     134        snd_emux_proc_init(emu, card, index);
     135#endif
     136        return 0;
     137}
     138
     139
     140/*
     141 */
     142int snd_emux_free(struct snd_emux *emu)
     143{
     144        unsigned long flags;
     145
     146        if (! emu)
     147                return -EINVAL;
     148
     149        spin_lock_irqsave(&emu->voice_lock, flags);
     150        if (emu->timer_active)
     151                del_timer(&emu->tlist);
     152        spin_unlock_irqrestore(&emu->voice_lock, flags);
    120153
    121154#ifdef CONFIG_PROC_FS
    122     snd_emux_proc_free(emu);
    123 #endif
    124     snd_emux_delete_virmidi(emu);
    125 #ifdef CONFIG_SND_OSSEMUL
    126     snd_emux_detach_seq_oss(emu);
    127 #endif
    128     snd_emux_detach_seq(emu);
    129 
    130     if (emu->sflist)
    131         snd_sf_free(emu->sflist);
    132 
    133     if (emu->voices)
    134         kfree(emu->voices);
    135 
    136     if (emu->name)
    137         kfree(emu->name);
    138 
    139     kfree(emu);
    140     return 0;
     155        snd_emux_proc_free(emu);
     156#endif
     157        snd_emux_delete_virmidi(emu);
     158#ifdef CONFIG_SND_SEQUENCER_OSS
     159        snd_emux_detach_seq_oss(emu);
     160#endif
     161        snd_emux_detach_seq(emu);
     162
     163        snd_emux_delete_hwdep(emu);
     164
     165        if (emu->sflist)
     166                snd_sf_free(emu->sflist);
     167
     168        kfree(emu->voices);
     169        kfree(emu->name);
     170        kfree(emu);
     171        return 0;
    141172}
    142173
     
    150181EXPORT_SYMBOL(snd_emux_unlock_voice);
    151182
     183/* soundfont.c */
     184EXPORT_SYMBOL(snd_sf_linear_to_log);
     185
    152186
    153187/*
     
    157191static int __init alsa_emux_init(void)
    158192{
    159     return 0;
     193        return 0;
    160194}
    161195
  • GPL/trunk/alsa-kernel/synth/emux/emux_effect.c

    r33 r34  
    2323 */
    2424
    25 #define __NO_VERSION__
    2625#include "emux_voice.h"
    2726#include <linux/slab.h>
     
    3433#define xoffsetof(type,tag)     ((long)(&((type)NULL)->tag) - (long)(NULL))
    3534
    36 #define parm_offset(tag)        xoffsetof(soundfont_voice_parm_t*, tag)
     35#define parm_offset(tag)        xoffsetof(struct soundfont_voice_parm *, tag)
    3736
    3837#define PARM_IS_BYTE            (1 << 0)
     
    5150
    5251static struct emux_parm_defs {
    53     int type;   /* byte or word */
    54     int low, high;      /* value range */
    55     long offset;        /* offset in parameter record (-1 = not written) */
    56     int update; /* flgas for real-time update */
     52        int type;       /* byte or word */
     53        int low, high;  /* value range */
     54        long offset;    /* offset in parameter record (-1 = not written) */
     55        int update;     /* flgas for real-time update */
    5756} parm_defs[EMUX_NUM_EFFECTS] = {
    58     {PARM_WORD, 0, 0x8000, parm_offset(moddelay), 0},   /* env1 delay */
    59     {PARM_BYTE_LO, 1, 0x80, parm_offset(modatkhld), 0}, /* env1 attack */
    60     {PARM_BYTE_HI, 0, 0x7e, parm_offset(modatkhld), 0}, /* env1 hold */
    61     {PARM_BYTE_LO, 1, 0x7f, parm_offset(moddcysus), 0}, /* env1 decay */
    62     {PARM_BYTE_LO, 1, 0x7f, parm_offset(modrelease), 0},        /* env1 release */
    63     {PARM_BYTE_HI, 0, 0x7f, parm_offset(moddcysus), 0}, /* env1 sustain */
    64     {PARM_BYTE_HI, 0, 0xff, parm_offset(pefe), 0},      /* env1 pitch */
    65     {PARM_BYTE_LO, 0, 0xff, parm_offset(pefe), 0},      /* env1 fc */
    66 
    67     {PARM_WORD, 0, 0x8000, parm_offset(voldelay), 0},   /* env2 delay */
    68     {PARM_BYTE_LO, 1, 0x80, parm_offset(volatkhld), 0}, /* env2 attack */
    69     {PARM_BYTE_HI, 0, 0x7e, parm_offset(volatkhld), 0}, /* env2 hold */
    70     {PARM_BYTE_LO, 1, 0x7f, parm_offset(voldcysus), 0}, /* env2 decay */
    71     {PARM_BYTE_LO, 1, 0x7f, parm_offset(volrelease), 0},        /* env2 release */
    72     {PARM_BYTE_HI, 0, 0x7f, parm_offset(voldcysus), 0}, /* env2 sustain */
    73 
    74     {PARM_WORD, 0, 0x8000, parm_offset(lfo1delay), 0},  /* lfo1 delay */
    75     {PARM_BYTE_LO, 0, 0xff, parm_offset(tremfrq), SNDRV_EMUX_UPDATE_TREMFREQ},  /* lfo1 freq */
    76     {PARM_SIGN_HI, -128, 127, parm_offset(tremfrq), SNDRV_EMUX_UPDATE_TREMFREQ},        /* lfo1 vol */
    77     {PARM_SIGN_HI, -128, 127, parm_offset(fmmod), SNDRV_EMUX_UPDATE_FMMOD},     /* lfo1 pitch */
    78     {PARM_BYTE_LO, 0, 0xff, parm_offset(fmmod), SNDRV_EMUX_UPDATE_FMMOD},       /* lfo1 cutoff */
    79 
    80     {PARM_WORD, 0, 0x8000, parm_offset(lfo2delay), 0},  /* lfo2 delay */
    81     {PARM_BYTE_LO, 0, 0xff, parm_offset(fm2frq2), SNDRV_EMUX_UPDATE_FM2FRQ2},   /* lfo2 freq */
    82     {PARM_SIGN_HI, -128, 127, parm_offset(fm2frq2), SNDRV_EMUX_UPDATE_FM2FRQ2}, /* lfo2 pitch */
    83 
    84     {PARM_WORD, 0, 0xffff, -1, SNDRV_EMUX_UPDATE_PITCH},        /* initial pitch */
    85     {PARM_BYTE, 0, 0xff, parm_offset(chorus), 0},       /* chorus */
    86     {PARM_BYTE, 0, 0xff, parm_offset(reverb), 0},       /* reverb */
    87     {PARM_BYTE, 0, 0xff, parm_offset(cutoff), SNDRV_EMUX_UPDATE_VOLUME},        /* cutoff */
    88     {PARM_BYTE, 0, 15, parm_offset(filterQ), SNDRV_EMUX_UPDATE_Q},      /* resonance */
    89 
    90     {PARM_WORD, 0, 0xffff, -1, 0},      /* sample start */
    91     {PARM_WORD, 0, 0xffff, -1, 0},      /* loop start */
    92     {PARM_WORD, 0, 0xffff, -1, 0},      /* loop end */
    93     {PARM_WORD, 0, 0xffff, -1, 0},      /* coarse sample start */
    94     {PARM_WORD, 0, 0xffff, -1, 0},      /* coarse loop start */
    95     {PARM_WORD, 0, 0xffff, -1, 0},      /* coarse loop end */
    96     {PARM_BYTE, 0, 0xff, -1, SNDRV_EMUX_UPDATE_VOLUME}, /* initial attenuation */
     57        {PARM_WORD, 0, 0x8000, parm_offset(moddelay), 0},       /* env1 delay */
     58        {PARM_BYTE_LO, 1, 0x80, parm_offset(modatkhld), 0},     /* env1 attack */
     59        {PARM_BYTE_HI, 0, 0x7e, parm_offset(modatkhld), 0},     /* env1 hold */
     60        {PARM_BYTE_LO, 1, 0x7f, parm_offset(moddcysus), 0},     /* env1 decay */
     61        {PARM_BYTE_LO, 1, 0x7f, parm_offset(modrelease), 0},    /* env1 release */
     62        {PARM_BYTE_HI, 0, 0x7f, parm_offset(moddcysus), 0},     /* env1 sustain */
     63        {PARM_BYTE_HI, 0, 0xff, parm_offset(pefe), 0},  /* env1 pitch */
     64        {PARM_BYTE_LO, 0, 0xff, parm_offset(pefe), 0},  /* env1 fc */
     65
     66        {PARM_WORD, 0, 0x8000, parm_offset(voldelay), 0},       /* env2 delay */
     67        {PARM_BYTE_LO, 1, 0x80, parm_offset(volatkhld), 0},     /* env2 attack */
     68        {PARM_BYTE_HI, 0, 0x7e, parm_offset(volatkhld), 0},     /* env2 hold */
     69        {PARM_BYTE_LO, 1, 0x7f, parm_offset(voldcysus), 0},     /* env2 decay */
     70        {PARM_BYTE_LO, 1, 0x7f, parm_offset(volrelease), 0},    /* env2 release */
     71        {PARM_BYTE_HI, 0, 0x7f, parm_offset(voldcysus), 0},     /* env2 sustain */
     72
     73        {PARM_WORD, 0, 0x8000, parm_offset(lfo1delay), 0},      /* lfo1 delay */
     74        {PARM_BYTE_LO, 0, 0xff, parm_offset(tremfrq), SNDRV_EMUX_UPDATE_TREMFREQ},      /* lfo1 freq */
     75        {PARM_SIGN_HI, -128, 127, parm_offset(tremfrq), SNDRV_EMUX_UPDATE_TREMFREQ},    /* lfo1 vol */
     76        {PARM_SIGN_HI, -128, 127, parm_offset(fmmod), SNDRV_EMUX_UPDATE_FMMOD}, /* lfo1 pitch */
     77        {PARM_BYTE_LO, 0, 0xff, parm_offset(fmmod), SNDRV_EMUX_UPDATE_FMMOD},   /* lfo1 cutoff */
     78
     79        {PARM_WORD, 0, 0x8000, parm_offset(lfo2delay), 0},      /* lfo2 delay */
     80        {PARM_BYTE_LO, 0, 0xff, parm_offset(fm2frq2), SNDRV_EMUX_UPDATE_FM2FRQ2},       /* lfo2 freq */
     81        {PARM_SIGN_HI, -128, 127, parm_offset(fm2frq2), SNDRV_EMUX_UPDATE_FM2FRQ2},     /* lfo2 pitch */
     82
     83        {PARM_WORD, 0, 0xffff, -1, SNDRV_EMUX_UPDATE_PITCH},    /* initial pitch */
     84        {PARM_BYTE, 0, 0xff, parm_offset(chorus), 0},   /* chorus */
     85        {PARM_BYTE, 0, 0xff, parm_offset(reverb), 0},   /* reverb */
     86        {PARM_BYTE, 0, 0xff, parm_offset(cutoff), SNDRV_EMUX_UPDATE_VOLUME},    /* cutoff */
     87        {PARM_BYTE, 0, 15, parm_offset(filterQ), SNDRV_EMUX_UPDATE_Q},  /* resonance */
     88
     89        {PARM_WORD, 0, 0xffff, -1, 0},  /* sample start */
     90        {PARM_WORD, 0, 0xffff, -1, 0},  /* loop start */
     91        {PARM_WORD, 0, 0xffff, -1, 0},  /* loop end */
     92        {PARM_WORD, 0, 0xffff, -1, 0},  /* coarse sample start */
     93        {PARM_WORD, 0, 0xffff, -1, 0},  /* coarse loop start */
     94        {PARM_WORD, 0, 0xffff, -1, 0},  /* coarse loop end */
     95        {PARM_BYTE, 0, 0xff, -1, SNDRV_EMUX_UPDATE_VOLUME},     /* initial attenuation */
    9796};
    9897
    9998/* set byte effect value */
    10099static void
    101 effect_set_byte(unsigned char *valp, snd_midi_channel_t *chan, int type)
    102 {
    103     short effect;
    104     snd_emux_effect_table_t *fx = chan->private;
    105 
    106     effect = fx->val[type];
    107     if (fx->flag[type] == EMUX_FX_FLAG_ADD) {
    108         if (parm_defs[type].type & PARM_IS_SIGNED)
    109             effect += *(char*)valp;
    110         else
    111             effect += *valp;
    112     }
    113     if (effect < parm_defs[type].low)
    114         effect = parm_defs[type].low;
    115     else if (effect > parm_defs[type].high)
    116         effect = parm_defs[type].high;
    117     *valp = (unsigned char)effect;
     100effect_set_byte(unsigned char *valp, struct snd_midi_channel *chan, int type)
     101{
     102        short effect;
     103        struct snd_emux_effect_table *fx = chan->private;
     104
     105        effect = fx->val[type];
     106        if (fx->flag[type] == EMUX_FX_FLAG_ADD) {
     107                if (parm_defs[type].type & PARM_IS_SIGNED)
     108                        effect += *(char*)valp;
     109                else
     110                        effect += *valp;
     111        }
     112        if (effect < parm_defs[type].low)
     113                effect = parm_defs[type].low;
     114        else if (effect > parm_defs[type].high)
     115                effect = parm_defs[type].high;
     116        *valp = (unsigned char)effect;
    118117}
    119118
    120119/* set word effect value */
    121120static void
    122 effect_set_word(unsigned short *valp, snd_midi_channel_t *chan, int type)
    123 {
    124     int effect;
    125     snd_emux_effect_table_t *fx = chan->private;
    126 
    127     effect = *(unsigned short*)&fx->val[type];
    128     if (fx->flag[type] == EMUX_FX_FLAG_ADD)
    129         effect += *valp;
    130     if (effect < parm_defs[type].low)
    131         effect = parm_defs[type].low;
    132     else if (effect > parm_defs[type].high)
    133         effect = parm_defs[type].high;
    134     *valp = (unsigned short)effect;
     121effect_set_word(unsigned short *valp, struct snd_midi_channel *chan, int type)
     122{
     123        int effect;
     124        struct snd_emux_effect_table *fx = chan->private;
     125
     126        effect = *(unsigned short*)&fx->val[type];
     127        if (fx->flag[type] == EMUX_FX_FLAG_ADD)
     128                effect += *valp;
     129        if (effect < parm_defs[type].low)
     130                effect = parm_defs[type].low;
     131        else if (effect > parm_defs[type].high)
     132                effect = parm_defs[type].high;
     133        *valp = (unsigned short)effect;
    135134}
    136135
    137136/* address offset */
    138137static int
    139 effect_get_offset(snd_midi_channel_t *chan, int lo, int hi, int mode)
    140 {
    141     int addr = 0;
    142     snd_emux_effect_table_t *fx = chan->private;
    143 
    144     if (fx->flag[hi])
    145         addr = (short)fx->val[hi];
    146     addr = addr << 15;
    147     if (fx->flag[lo])
    148         addr += (short)fx->val[lo];
    149     if (!(mode & SNDRV_SFNT_SAMPLE_8BITS))
    150         addr /= 2;
    151     return addr;
    152 }
    153 
    154 #ifdef CONFIG_SND_OSSEMUL
     138effect_get_offset(struct snd_midi_channel *chan, int lo, int hi, int mode)
     139{
     140        int addr = 0;
     141        struct snd_emux_effect_table *fx = chan->private;
     142
     143        if (fx->flag[hi])
     144                addr = (short)fx->val[hi];
     145        addr = addr << 15;
     146        if (fx->flag[lo])
     147                addr += (short)fx->val[lo];
     148        if (!(mode & SNDRV_SFNT_SAMPLE_8BITS))
     149                addr /= 2;
     150        return addr;
     151}
     152
     153#ifdef CONFIG_SND_SEQUENCER_OSS
    155154/* change effects - for OSS sequencer compatibility */
    156155void
    157 snd_emux_send_effect_oss(snd_emux_port_t *port, snd_midi_channel_t *chan, int type, int val)
    158 {
    159     int mode;
    160 
    161     if (type & 0x40)
    162         mode = EMUX_FX_FLAG_OFF;
    163     else if (type & 0x80)
    164         mode = EMUX_FX_FLAG_ADD;
    165     else
    166         mode = EMUX_FX_FLAG_SET;
    167     type &= 0x3f;
    168 
    169     snd_emux_send_effect(port, chan, type, val, mode);
     156snd_emux_send_effect_oss(struct snd_emux_port *port,
     157                         struct snd_midi_channel *chan, int type, int val)
     158{
     159        int mode;
     160
     161        if (type & 0x40)
     162                mode = EMUX_FX_FLAG_OFF;
     163        else if (type & 0x80)
     164                mode = EMUX_FX_FLAG_ADD;
     165        else
     166                mode = EMUX_FX_FLAG_SET;
     167        type &= 0x3f;
     168
     169        snd_emux_send_effect(port, chan, type, val, mode);
    170170}
    171171#endif
     
    175175 */
    176176void
    177 snd_emux_send_effect(snd_emux_port_t *port, snd_midi_channel_t *chan, int type, int val, int mode)
    178 {
    179     int i;
    180     int offset;
    181     unsigned char *srcp, *origp;
    182     snd_emux_t *emu;
    183     snd_emux_effect_table_t *fx;
    184     unsigned long flags;
    185 
    186     emu = port->emu;
    187     fx = chan->private;
    188     if (emu == NULL || fx == NULL)
    189         return;
    190     if (type < 0 || type >= EMUX_NUM_EFFECTS)
    191         return;
    192 
    193     fx->val[type] = val;
    194     fx->flag[type] = mode;
    195 
    196     /* do we need to modify the register in realtime ? */
    197     if (! parm_defs[type].update || (offset = parm_defs[type].offset) < 0)
    198         return;
     177snd_emux_send_effect(struct snd_emux_port *port, struct snd_midi_channel *chan,
     178                     int type, int val, int mode)
     179{
     180        int i;
     181        int offset;
     182        unsigned char *srcp, *origp;
     183        struct snd_emux *emu;
     184        struct snd_emux_effect_table *fx;
     185        unsigned long flags;
     186
     187        emu = port->emu;
     188        fx = chan->private;
     189        if (emu == NULL || fx == NULL)
     190                return;
     191        if (type < 0 || type >= EMUX_NUM_EFFECTS)
     192                return;
     193
     194        fx->val[type] = val;
     195        fx->flag[type] = mode;
     196
     197        /* do we need to modify the register in realtime ? */
     198        if (! parm_defs[type].update || (offset = parm_defs[type].offset) < 0)
     199                return;
    199200
    200201#ifdef SNDRV_LITTLE_ENDIAN
    201     if (parm_defs[type].type & PARM_IS_ALIGN_HI)
    202         offset++;
     202        if (parm_defs[type].type & PARM_IS_ALIGN_HI)
     203                offset++;
    203204#else
    204     if (parm_defs[type].type & PARM_IS_ALIGN_LO)
    205         offset++;
     205        if (parm_defs[type].type & PARM_IS_ALIGN_LO)
     206                offset++;
    206207#endif
    207     /* modify the register values */
    208     spin_lock_irqsave(&emu->voice_lock, flags);
    209     for (i = 0; i < emu->max_voices; i++) {
    210         snd_emux_voice_t *vp = &emu->voices[i];
    211         if (!STATE_IS_PLAYING(vp->state) || vp->chan != chan)
    212             continue;
    213         srcp = (unsigned char*)&vp->reg.parm + offset;
    214         origp = (unsigned char*)&vp->zone->v.parm + offset;
    215         if (parm_defs[i].type & PARM_IS_BYTE) {
    216             *srcp = *origp;
    217             effect_set_byte(srcp, chan, type);
    218         } else {
    219             *(unsigned short*)srcp = *(unsigned short*)origp;
    220             effect_set_word((unsigned short*)srcp, chan, type);
    221         }
    222     }
    223     spin_unlock_irqrestore(&emu->voice_lock, flags);
    224 
    225     /* activate them */
    226     snd_emux_update_channel(port, chan, parm_defs[type].update);
     208        /* modify the register values */
     209        spin_lock_irqsave(&emu->voice_lock, flags);
     210        for (i = 0; i < emu->max_voices; i++) {
     211                struct snd_emux_voice *vp = &emu->voices[i];
     212                if (!STATE_IS_PLAYING(vp->state) || vp->chan != chan)
     213                        continue;
     214                srcp = (unsigned char*)&vp->reg.parm + offset;
     215                origp = (unsigned char*)&vp->zone->v.parm + offset;
     216                if (parm_defs[i].type & PARM_IS_BYTE) {
     217                        *srcp = *origp;
     218                        effect_set_byte(srcp, chan, type);
     219                } else {
     220                        *(unsigned short*)srcp = *(unsigned short*)origp;
     221                        effect_set_word((unsigned short*)srcp, chan, type);
     222                }
     223        }
     224        spin_unlock_irqrestore(&emu->voice_lock, flags);
     225
     226        /* activate them */
     227        snd_emux_update_channel(port, chan, parm_defs[type].update);
    227228}
    228229
     
    230231/* copy wavetable registers to voice table */
    231232void
    232 snd_emux_setup_effect(snd_emux_voice_t *vp)
    233 {
    234     snd_midi_channel_t *chan = vp->chan;
    235     snd_emux_effect_table_t *fx;
    236     unsigned char *srcp;
    237     int i;
    238 
    239     if (! (fx = chan->private))
    240         return;
    241 
    242     /* modify the register values via effect table */
    243     for (i = 0; i < EMUX_FX_END; i++) {
    244         int offset;
    245         if (! fx->flag[i] || (offset = parm_defs[i].offset) < 0)
    246             continue;
     233snd_emux_setup_effect(struct snd_emux_voice *vp)
     234{
     235        struct snd_midi_channel *chan = vp->chan;
     236        struct snd_emux_effect_table *fx;
     237        unsigned char *srcp;
     238        int i;
     239
     240        if (! (fx = chan->private))
     241                return;
     242
     243        /* modify the register values via effect table */
     244        for (i = 0; i < EMUX_FX_END; i++) {
     245                int offset;
     246                if (! fx->flag[i] || (offset = parm_defs[i].offset) < 0)
     247                        continue;
    247248#ifdef SNDRV_LITTLE_ENDIAN
    248         if (parm_defs[i].type & PARM_IS_ALIGN_HI)
    249             offset++;
     249                if (parm_defs[i].type & PARM_IS_ALIGN_HI)
     250                        offset++;
    250251#else
    251         if (parm_defs[i].type & PARM_IS_ALIGN_LO)
    252             offset++;
     252                if (parm_defs[i].type & PARM_IS_ALIGN_LO)
     253                        offset++;
    253254#endif
    254         srcp = (unsigned char*)&vp->reg.parm + offset;
    255         if (parm_defs[i].type & PARM_IS_BYTE)
    256             effect_set_byte(srcp, chan, i);
    257         else
    258             effect_set_word((unsigned short*)srcp, chan, i);
    259     }
    260 
    261     /* correct sample and loop points */
    262     vp->reg.start += effect_get_offset(chan, EMUX_FX_SAMPLE_START,
    263                                        EMUX_FX_COARSE_SAMPLE_START,
    264                                        vp->reg.sample_mode);
    265 
    266     vp->reg.loopstart += effect_get_offset(chan, EMUX_FX_LOOP_START,
    267                                            EMUX_FX_COARSE_LOOP_START,
    268                                            vp->reg.sample_mode);
    269 
    270     vp->reg.loopend += effect_get_offset(chan, EMUX_FX_LOOP_END,
    271                                          EMUX_FX_COARSE_LOOP_END,
    272                                          vp->reg.sample_mode);
     255                srcp = (unsigned char*)&vp->reg.parm + offset;
     256                if (parm_defs[i].type & PARM_IS_BYTE)
     257                        effect_set_byte(srcp, chan, i);
     258                else
     259                        effect_set_word((unsigned short*)srcp, chan, i);
     260        }
     261
     262        /* correct sample and loop points */
     263        vp->reg.start += effect_get_offset(chan, EMUX_FX_SAMPLE_START,
     264                                           EMUX_FX_COARSE_SAMPLE_START,
     265                                           vp->reg.sample_mode);
     266
     267        vp->reg.loopstart += effect_get_offset(chan, EMUX_FX_LOOP_START,
     268                                               EMUX_FX_COARSE_LOOP_START,
     269                                               vp->reg.sample_mode);
     270
     271        vp->reg.loopend += effect_get_offset(chan, EMUX_FX_LOOP_END,
     272                                             EMUX_FX_COARSE_LOOP_END,
     273                                             vp->reg.sample_mode);
    273274}
    274275
     
    277278 */
    278279void
    279 snd_emux_create_effect(snd_emux_port_t *p)
    280 {
    281     int i;
    282     p->effect = kcalloc(p->chset.max_channels, sizeof(snd_emux_effect_table_t), GFP_KERNEL);
    283     if (p->effect) {
    284         for (i = 0; i < p->chset.max_channels; i++)
    285             p->chset.channels[i].private = p->effect + i;
    286     } else {
    287         for (i = 0; i < p->chset.max_channels; i++)
    288             p->chset.channels[i].private = NULL;
    289     }
    290 }
    291 
    292 void
    293 snd_emux_delete_effect(snd_emux_port_t *p)
    294 {
    295     if (p->effect) {
    296         kfree(p->effect);
    297         p->effect = NULL;
    298     }
    299 }
    300 
    301 void
    302 snd_emux_clear_effect(snd_emux_port_t *p)
    303 {
    304     if (p->effect) {
    305         memset(p->effect, 0, sizeof(snd_emux_effect_table_t) * p->chset.max_channels);
    306     }
     280snd_emux_create_effect(struct snd_emux_port *p)
     281{
     282        int i;
     283        p->effect = kcalloc(p->chset.max_channels,
     284                            sizeof(struct snd_emux_effect_table), GFP_KERNEL);
     285        if (p->effect) {
     286                for (i = 0; i < p->chset.max_channels; i++)
     287                        p->chset.channels[i].private = p->effect + i;
     288        } else {
     289                for (i = 0; i < p->chset.max_channels; i++)
     290                        p->chset.channels[i].private = NULL;
     291        }
     292}
     293
     294void
     295snd_emux_delete_effect(struct snd_emux_port *p)
     296{
     297        kfree(p->effect);
     298        p->effect = NULL;
     299}
     300
     301void
     302snd_emux_clear_effect(struct snd_emux_port *p)
     303{
     304        if (p->effect) {
     305                memset(p->effect, 0, sizeof(struct snd_emux_effect_table) *
     306                      p->chset.max_channels);
     307        }
    307308}
    308309
  • GPL/trunk/alsa-kernel/synth/emux/emux_nrpn.c

    r33 r34  
    1616 *   You should have received a copy of the GNU General Public License
    1717 *   along with this program; if not, write to the Free Software
    18  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
     18 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
    1919 *
    2020 */
    2121
    2222#include "emux_voice.h"
    23 
    24 #define NELEM(arr) (sizeof(arr)/sizeof((arr)[0]))
     23#include <sound/asoundef.h>
    2524
    2625/*
     
    2928
    3029/* NRPN / CC -> Emu8000 parameter converter */
    31 typedef struct {
    32     int control;
    33     int effect;
    34     int (*convert)(int val);
    35 } nrpn_conv_table;
     30struct nrpn_conv_table {
     31        int control;
     32        int effect;
     33        int (*convert)(int val);
     34};
    3635
    3736/* effect sensitivity */
     
    5049 */
    5150
    52 static int send_converted_effect(nrpn_conv_table *table, int num_tables,
    53                                  snd_emux_port_t *port, snd_midi_channel_t *chan,
    54                                  int type, int val, int mode)
    55 {
    56     int i, cval;
    57     for (i = 0; i < num_tables; i++) {
    58         if (table[i].control == type) {
    59             cval = table[i].convert(val);
    60             snd_emux_send_effect(port, chan, table[i].effect,
    61                                  cval, mode);
    62             return 1;
    63         }
    64     }
    65     return 0;
     51static int send_converted_effect(struct nrpn_conv_table *table, int num_tables,
     52                                 struct snd_emux_port *port,
     53                                 struct snd_midi_channel *chan,
     54                                 int type, int val, int mode)
     55{
     56        int i, cval;
     57        for (i = 0; i < num_tables; i++) {
     58                if (table[i].control == type) {
     59                        cval = table[i].convert(val);
     60                        snd_emux_send_effect(port, chan, table[i].effect,
     61                                             cval, mode);
     62                        return 1;
     63                }
     64        }
     65        return 0;
    6666}
    6767
     
    7777 *  adjusted for chaos 8MB soundfonts
    7878 */
    79 static int gs_sense[] =
    80 {
    81     DEF_FX_CUTOFF, DEF_FX_RESONANCE, DEF_FX_ATTACK, DEF_FX_RELEASE,
    82     DEF_FX_VIBRATE, DEF_FX_VIBDEPTH, DEF_FX_VIBDELAY
     79static int gs_sense[] = 
     80{
     81        DEF_FX_CUTOFF, DEF_FX_RESONANCE, DEF_FX_ATTACK, DEF_FX_RELEASE,
     82        DEF_FX_VIBRATE, DEF_FX_VIBDEPTH, DEF_FX_VIBDELAY
    8383};
    8484
     
    8686 * adjusted for chaos 8MB soundfonts
    8787 */
    88 static int xg_sense[] =
    89 {
    90     DEF_FX_CUTOFF, DEF_FX_RESONANCE, DEF_FX_ATTACK, DEF_FX_RELEASE,
    91     DEF_FX_VIBRATE, DEF_FX_VIBDEPTH, DEF_FX_VIBDELAY
     88static int xg_sense[] = 
     89{
     90        DEF_FX_CUTOFF, DEF_FX_RESONANCE, DEF_FX_ATTACK, DEF_FX_RELEASE,
     91        DEF_FX_VIBRATE, DEF_FX_VIBDEPTH, DEF_FX_VIBDELAY
    9292};
    9393
     
    141141static int fx_delay(int val)
    142142{
    143     return (unsigned short)snd_sf_calc_parm_delay(val);
     143        return (unsigned short)snd_sf_calc_parm_delay(val);
    144144}
    145145
    146146static int fx_attack(int val)
    147147{
    148     return (unsigned short)snd_sf_calc_parm_attack(val);
     148        return (unsigned short)snd_sf_calc_parm_attack(val);
    149149}
    150150
    151151static int fx_hold(int val)
    152152{
    153     return (unsigned short)snd_sf_calc_parm_hold(val);
     153        return (unsigned short)snd_sf_calc_parm_hold(val);
    154154}
    155155
    156156static int fx_decay(int val)
    157157{
    158     return (unsigned short)snd_sf_calc_parm_decay(val);
     158        return (unsigned short)snd_sf_calc_parm_decay(val);
    159159}
    160160
    161161static int fx_the_value(int val)
    162162{
    163     return (unsigned short)(val & 0xff);
     163        return (unsigned short)(val & 0xff);
    164164}
    165165
    166166static int fx_twice_value(int val)
    167167{
    168     return (unsigned short)((val * 2) & 0xff);
     168        return (unsigned short)((val * 2) & 0xff);
    169169}
    170170
    171171static int fx_conv_pitch(int val)
    172172{
    173     return (short)(val * 4096 / 1200);
     173        return (short)(val * 4096 / 1200);
    174174}
    175175
    176176static int fx_conv_Q(int val)
    177177{
    178     return (unsigned short)((val / 8) & 0xff);
    179 }
    180 
    181 
    182 static nrpn_conv_table awe_effects[] =
    183 {
    184     { 0, EMUX_FX_LFO1_DELAY,    fx_lfo1_delay},
    185     { 1, EMUX_FX_LFO1_FREQ,     fx_lfo1_freq},
    186     { 2, EMUX_FX_LFO2_DELAY,    fx_lfo2_delay},
    187     { 3, EMUX_FX_LFO2_FREQ,     fx_lfo2_freq},
    188 
    189     { 4, EMUX_FX_ENV1_DELAY,    fx_env1_delay},
    190     { 5, EMUX_FX_ENV1_ATTACK,fx_env1_attack},
    191     { 6, EMUX_FX_ENV1_HOLD,     fx_env1_hold},
    192     { 7, EMUX_FX_ENV1_DECAY,    fx_env1_decay},
    193     { 8, EMUX_FX_ENV1_SUSTAIN,  fx_env1_sustain},
    194     { 9, EMUX_FX_ENV1_RELEASE,  fx_env1_release},
    195 
    196     {10, EMUX_FX_ENV2_DELAY,    fx_env2_delay},
    197     {11, EMUX_FX_ENV2_ATTACK,   fx_env2_attack},
    198     {12, EMUX_FX_ENV2_HOLD,     fx_env2_hold},
    199     {13, EMUX_FX_ENV2_DECAY,    fx_env2_decay},
    200     {14, EMUX_FX_ENV2_SUSTAIN,  fx_env2_sustain},
    201     {15, EMUX_FX_ENV2_RELEASE,  fx_env2_release},
    202 
    203     {16, EMUX_FX_INIT_PITCH,    fx_init_pitch},
    204     {17, EMUX_FX_LFO1_PITCH,    fx_lfo1_pitch},
    205     {18, EMUX_FX_LFO2_PITCH,    fx_lfo2_pitch},
    206     {19, EMUX_FX_ENV1_PITCH,    fx_env1_pitch},
    207     {20, EMUX_FX_LFO1_VOLUME,   fx_lfo1_volume},
    208     {21, EMUX_FX_CUTOFF,                fx_cutoff},
    209     {22, EMUX_FX_FILTERQ,       fx_filterQ},
    210     {23, EMUX_FX_LFO1_CUTOFF,   fx_lfo1_cutoff},
    211     {24, EMUX_FX_ENV1_CUTOFF,   fx_env1_cutoff},
    212     {25, EMUX_FX_CHORUS,                fx_chorus},
    213     {26, EMUX_FX_REVERB,                fx_reverb},
    214 };
    215 
    216 static int num_awe_effects = NELEM(awe_effects);
     178        return (unsigned short)((val / 8) & 0xff);
     179}
     180
     181
     182static struct nrpn_conv_table awe_effects[] =
     183{
     184        { 0, EMUX_FX_LFO1_DELAY,        fx_lfo1_delay},
     185        { 1, EMUX_FX_LFO1_FREQ, fx_lfo1_freq},
     186        { 2, EMUX_FX_LFO2_DELAY,        fx_lfo2_delay},
     187        { 3, EMUX_FX_LFO2_FREQ, fx_lfo2_freq},
     188
     189        { 4, EMUX_FX_ENV1_DELAY,        fx_env1_delay},
     190        { 5, EMUX_FX_ENV1_ATTACK,fx_env1_attack},
     191        { 6, EMUX_FX_ENV1_HOLD, fx_env1_hold},
     192        { 7, EMUX_FX_ENV1_DECAY,        fx_env1_decay},
     193        { 8, EMUX_FX_ENV1_SUSTAIN,      fx_env1_sustain},
     194        { 9, EMUX_FX_ENV1_RELEASE,      fx_env1_release},
     195
     196        {10, EMUX_FX_ENV2_DELAY,        fx_env2_delay},
     197        {11, EMUX_FX_ENV2_ATTACK,       fx_env2_attack},
     198        {12, EMUX_FX_ENV2_HOLD, fx_env2_hold},
     199        {13, EMUX_FX_ENV2_DECAY,        fx_env2_decay},
     200        {14, EMUX_FX_ENV2_SUSTAIN,      fx_env2_sustain},
     201        {15, EMUX_FX_ENV2_RELEASE,      fx_env2_release},
     202
     203        {16, EMUX_FX_INIT_PITCH,        fx_init_pitch},
     204        {17, EMUX_FX_LFO1_PITCH,        fx_lfo1_pitch},
     205        {18, EMUX_FX_LFO2_PITCH,        fx_lfo2_pitch},
     206        {19, EMUX_FX_ENV1_PITCH,        fx_env1_pitch},
     207        {20, EMUX_FX_LFO1_VOLUME,       fx_lfo1_volume},
     208        {21, EMUX_FX_CUTOFF,            fx_cutoff},
     209        {22, EMUX_FX_FILTERQ,   fx_filterQ},
     210        {23, EMUX_FX_LFO1_CUTOFF,       fx_lfo1_cutoff},
     211        {24, EMUX_FX_ENV1_CUTOFF,       fx_env1_cutoff},
     212        {25, EMUX_FX_CHORUS,            fx_chorus},
     213        {26, EMUX_FX_REVERB,            fx_reverb},
     214};
    217215
    218216
     
    224222static int gs_cutoff(int val)
    225223{
    226     return (val - 64) * gs_sense[FX_CUTOFF] / 50;
     224        return (val - 64) * gs_sense[FX_CUTOFF] / 50;
    227225}
    228226
     
    230228static int gs_filterQ(int val)
    231229{
    232     return (val - 64) * gs_sense[FX_RESONANCE] / 50;
     230        return (val - 64) * gs_sense[FX_RESONANCE] / 50;
    233231}
    234232
     
    236234static int gs_attack(int val)
    237235{
    238     return -(val - 64) * gs_sense[FX_ATTACK] / 50;
     236        return -(val - 64) * gs_sense[FX_ATTACK] / 50;
    239237}
    240238
     
    242240static int gs_decay(int val)
    243241{
    244     return -(val - 64) * gs_sense[FX_RELEASE] / 50;
     242        return -(val - 64) * gs_sense[FX_RELEASE] / 50;
    245243}
    246244
     
    248246static int gs_release(int val)
    249247{
    250     return -(val - 64) * gs_sense[FX_RELEASE] / 50;
     248        return -(val - 64) * gs_sense[FX_RELEASE] / 50;
    251249}
    252250
     
    254252static int gs_vib_rate(int val)
    255253{
    256     return (val - 64) * gs_sense[FX_VIBRATE] / 50;
     254        return (val - 64) * gs_sense[FX_VIBRATE] / 50;
    257255}
    258256
     
    260258static int gs_vib_depth(int val)
    261259{
    262     return (val - 64) * gs_sense[FX_VIBDEPTH] / 50;
     260        return (val - 64) * gs_sense[FX_VIBDEPTH] / 50;
    263261}
    264262
     
    266264static int gs_vib_delay(int val)
    267265{
    268     return -(val - 64) * gs_sense[FX_VIBDELAY] / 50;
    269 }
    270 
    271 static nrpn_conv_table gs_effects[] =
    272 {
    273     {32, EMUX_FX_CUTOFF,        gs_cutoff},
    274     {33, EMUX_FX_FILTERQ,       gs_filterQ},
    275     {99, EMUX_FX_ENV2_ATTACK, gs_attack},
    276     {100, EMUX_FX_ENV2_DECAY, gs_decay},
    277     {102, EMUX_FX_ENV2_RELEASE, gs_release},
    278     {8, EMUX_FX_LFO1_FREQ, gs_vib_rate},
    279     {9, EMUX_FX_LFO1_VOLUME, gs_vib_depth},
    280     {10, EMUX_FX_LFO1_DELAY, gs_vib_delay},
    281 };
    282 
    283 static int num_gs_effects = NELEM(gs_effects);
     266        return -(val - 64) * gs_sense[FX_VIBDELAY] / 50;
     267}
     268
     269static struct nrpn_conv_table gs_effects[] =
     270{
     271        {32, EMUX_FX_CUTOFF,    gs_cutoff},
     272        {33, EMUX_FX_FILTERQ,   gs_filterQ},
     273        {99, EMUX_FX_ENV2_ATTACK, gs_attack},
     274        {100, EMUX_FX_ENV2_DECAY, gs_decay},
     275        {102, EMUX_FX_ENV2_RELEASE, gs_release},
     276        {8, EMUX_FX_LFO1_FREQ, gs_vib_rate},
     277        {9, EMUX_FX_LFO1_VOLUME, gs_vib_depth},
     278        {10, EMUX_FX_LFO1_DELAY, gs_vib_delay},
     279};
    284280
    285281
     
    288284 */
    289285void
    290     snd_emux_nrpn(void *p, snd_midi_channel_t *chan, snd_midi_channel_set_t *chset)
    291 {
    292     snd_emux_port_t *port;
    293 
    294     port = p;
    295     snd_assert(port != NULL, return);
    296     snd_assert(chan != NULL, return);
    297 
    298     if (chan->control[MIDI_CTL_NONREG_PARM_NUM_MSB] == 127 &&
    299         chan->control[MIDI_CTL_NONREG_PARM_NUM_LSB] <= 26) {
    300         int val;
    301         /* Win/DOS AWE32 specific NRPNs */
    302         /* both MSB/LSB necessary */
    303         val = (chan->control[MIDI_CTL_MSB_DATA_ENTRY] << 7) |
    304             chan->control[MIDI_CTL_LSB_DATA_ENTRY];
    305         val -= 8192;
    306         send_converted_effect
    307             (awe_effects, num_awe_effects,
    308              port, chan, chan->control[MIDI_CTL_NONREG_PARM_NUM_LSB],
    309              val, EMUX_FX_FLAG_SET);
    310         return;
    311     }
    312 
    313     if (port->chset.midi_mode == SNDRV_MIDI_MODE_GS &&
    314         chan->control[MIDI_CTL_NONREG_PARM_NUM_MSB] == 1) {
    315         int val;
    316         /* GS specific NRPNs */
    317         /* only MSB is valid */
    318         val = chan->control[MIDI_CTL_MSB_DATA_ENTRY];
    319         send_converted_effect
    320             (gs_effects, num_gs_effects,
    321              port, chan, chan->control[MIDI_CTL_NONREG_PARM_NUM_LSB],
    322              val, EMUX_FX_FLAG_ADD);
    323         return;
    324     }
     286snd_emux_nrpn(void *p, struct snd_midi_channel *chan,
     287              struct snd_midi_channel_set *chset)
     288{
     289        struct snd_emux_port *port;
     290
     291        port = p;
     292        snd_assert(port != NULL, return);
     293        snd_assert(chan != NULL, return);
     294
     295        if (chan->control[MIDI_CTL_NONREG_PARM_NUM_MSB] == 127 &&
     296            chan->control[MIDI_CTL_NONREG_PARM_NUM_LSB] <= 26) {
     297                int val;
     298                /* Win/DOS AWE32 specific NRPNs */
     299                /* both MSB/LSB necessary */
     300                val = (chan->control[MIDI_CTL_MSB_DATA_ENTRY] << 7) |
     301                        chan->control[MIDI_CTL_LSB_DATA_ENTRY];
     302                val -= 8192;
     303                send_converted_effect
     304                        (awe_effects, ARRAY_SIZE(awe_effects),
     305                         port, chan, chan->control[MIDI_CTL_NONREG_PARM_NUM_LSB],
     306                         val, EMUX_FX_FLAG_SET);
     307                return;
     308        }
     309
     310        if (port->chset.midi_mode == SNDRV_MIDI_MODE_GS &&
     311            chan->control[MIDI_CTL_NONREG_PARM_NUM_MSB] == 1) {
     312                int val;
     313                /* GS specific NRPNs */
     314                /* only MSB is valid */
     315                val = chan->control[MIDI_CTL_MSB_DATA_ENTRY];
     316                send_converted_effect
     317                        (gs_effects, ARRAY_SIZE(gs_effects),
     318                         port, chan, chan->control[MIDI_CTL_NONREG_PARM_NUM_LSB],
     319                         val, EMUX_FX_FLAG_ADD);
     320                return;
     321        }
    325322}
    326323
     
    333330static int xg_cutoff(int val)
    334331{
    335     return (val - 64) * xg_sense[FX_CUTOFF] / 64;
     332        return (val - 64) * xg_sense[FX_CUTOFF] / 64;
    336333}
    337334
     
    339336static int xg_filterQ(int val)
    340337{
    341     return (val - 64) * xg_sense[FX_RESONANCE] / 64;
     338        return (val - 64) * xg_sense[FX_RESONANCE] / 64;
    342339}
    343340
     
    345342static int xg_attack(int val)
    346343{
    347     return -(val - 64) * xg_sense[FX_ATTACK] / 64;
     344        return -(val - 64) * xg_sense[FX_ATTACK] / 64;
    348345}
    349346
     
    351348static int xg_release(int val)
    352349{
    353     return -(val - 64) * xg_sense[FX_RELEASE] / 64;
    354 }
    355 
    356 static nrpn_conv_table xg_effects[] =
    357 {
    358     {71, EMUX_FX_CUTOFF,        xg_cutoff},
    359     {74, EMUX_FX_FILTERQ,       xg_filterQ},
    360     {72, EMUX_FX_ENV2_RELEASE, xg_release},
    361     {73, EMUX_FX_ENV2_ATTACK, xg_attack},
    362 };
    363 
    364 static int num_xg_effects = NELEM(xg_effects);
     350        return -(val - 64) * xg_sense[FX_RELEASE] / 64;
     351}
     352
     353static struct nrpn_conv_table xg_effects[] =
     354{
     355        {71, EMUX_FX_CUTOFF,    xg_cutoff},
     356        {74, EMUX_FX_FILTERQ,   xg_filterQ},
     357        {72, EMUX_FX_ENV2_RELEASE, xg_release},
     358        {73, EMUX_FX_ENV2_ATTACK, xg_attack},
     359};
    365360
    366361int
    367     snd_emux_xg_control(snd_emux_port_t *port, snd_midi_channel_t *chan, int param)
    368 {
    369     return send_converted_effect(xg_effects, num_xg_effects,
    370                                  port, chan, param,
    371                                  chan->control[param],
    372                                  EMUX_FX_FLAG_ADD);
     362snd_emux_xg_control(struct snd_emux_port *port, struct snd_midi_channel *chan,
     363                    int param)
     364{
     365        return send_converted_effect(xg_effects, ARRAY_SIZE(xg_effects),
     366                                     port, chan, param,
     367                                     chan->control[param],
     368                                     EMUX_FX_FLAG_ADD);
    373369}
    374370
     
    377373 */
    378374void
    379 snd_emux_sysex(void *p, unsigned char *buf, int len, int parsed, snd_midi_channel_set_t *chset)
    380 {
    381     snd_emux_port_t *port;
    382     snd_emux_t *emu;
    383 
    384     port = p;
    385     snd_assert(port != NULL, return);
    386     snd_assert(chset != NULL, return);
    387     emu = port->emu;
    388 
    389     switch (parsed) {
    390     case SNDRV_MIDI_SYSEX_GS_MASTER_VOLUME:
    391         snd_emux_update_port(port, SNDRV_EMUX_UPDATE_VOLUME);
    392         break;
    393     default:
    394         if (emu->ops.sysex)
    395             emu->ops.sysex(emu, buf, len, parsed, chset);
    396         break;
    397     }
    398 }
    399 
     375snd_emux_sysex(void *p, unsigned char *buf, int len, int parsed,
     376               struct snd_midi_channel_set *chset)
     377{
     378        struct snd_emux_port *port;
     379        struct snd_emux *emu;
     380
     381        port = p;
     382        snd_assert(port != NULL, return);
     383        snd_assert(chset != NULL, return);
     384        emu = port->emu;
     385
     386        switch (parsed) {
     387        case SNDRV_MIDI_SYSEX_GS_MASTER_VOLUME:
     388                snd_emux_update_port(port, SNDRV_EMUX_UPDATE_VOLUME);
     389                break;
     390        default:
     391                if (emu->ops.sysex)
     392                        emu->ops.sysex(emu, buf, len, parsed, chset);
     393                break;
     394        }
     395}
     396
  • GPL/trunk/alsa-kernel/synth/emux/emux_proc.c

    r33 r34  
    1919 */
    2020
    21 #define __NO_VERSION__
    2221#include <sound/driver.h>
    2322#include <linux/wait.h>
     
    3231
    3332static void
    34     snd_emux_proc_info_read(snd_info_entry_t *entry,
    35                             snd_info_buffer_t *buf)
     33snd_emux_proc_info_read(struct snd_info_entry *entry,
     34                        struct snd_info_buffer *buf)
    3635{
    37     snd_emux_t *emu;
    38     int i;
     36        struct snd_emux *emu;
     37        int i;
    3938
    40     emu = entry->private_data;
    41     down(&emu->register_mutex);
    42     if (emu->name)
    43         snd_iprintf(buf, "Device: %s\n", emu->name);
    44     snd_iprintf(buf, "Ports: %d\n", emu->num_ports);
    45     snd_iprintf(buf, "Addresses:");
    46     for (i = 0; i < emu->num_ports; i++)
    47         snd_iprintf(buf, " %d:%d", emu->client, emu->ports[i]);
    48     snd_iprintf(buf, "\n");
    49     snd_iprintf(buf, "Use Counter: %d\n", emu->used);
    50     snd_iprintf(buf, "Max Voices: %d\n", emu->max_voices);
    51     snd_iprintf(buf, "Allocated Voices: %d\n", emu->num_voices);
    52     if (emu->memhdr) {
    53         snd_iprintf(buf, "Memory Size: %d\n", emu->memhdr->size);
    54         snd_iprintf(buf, "Memory Available: %d\n", snd_util_mem_avail(emu->memhdr));
    55         snd_iprintf(buf, "Allocated Blocks: %d\n", emu->memhdr->nblocks);
    56     } else {
    57         snd_iprintf(buf, "Memory Size: 0\n");
    58     }
    59     if (emu->sflist) {
    60         down(&emu->sflist->presets_mutex);
    61         snd_iprintf(buf, "SoundFonts: %d\n", emu->sflist->fonts_size);
    62         snd_iprintf(buf, "Instruments: %d\n", emu->sflist->zone_counter);
    63         snd_iprintf(buf, "Samples: %d\n", emu->sflist->sample_counter);
    64         snd_iprintf(buf, "Locked Instruments: %d\n", emu->sflist->zone_locked);
    65         snd_iprintf(buf, "Locked Samples: %d\n", emu->sflist->sample_locked);
    66         up(&emu->sflist->presets_mutex);
    67     }
     39        emu = entry->private_data;
     40        down(&emu->register_mutex);
     41        if (emu->name)
     42                snd_iprintf(buf, "Device: %s\n", emu->name);
     43        snd_iprintf(buf, "Ports: %d\n", emu->num_ports);
     44        snd_iprintf(buf, "Addresses:");
     45        for (i = 0; i < emu->num_ports; i++)
     46                snd_iprintf(buf, " %d:%d", emu->client, emu->ports[i]);
     47        snd_iprintf(buf, "\n");
     48        snd_iprintf(buf, "Use Counter: %d\n", emu->used);
     49        snd_iprintf(buf, "Max Voices: %d\n", emu->max_voices);
     50        snd_iprintf(buf, "Allocated Voices: %d\n", emu->num_voices);
     51        if (emu->memhdr) {
     52                snd_iprintf(buf, "Memory Size: %d\n", emu->memhdr->size);
     53                snd_iprintf(buf, "Memory Available: %d\n", snd_util_mem_avail(emu->memhdr));
     54                snd_iprintf(buf, "Allocated Blocks: %d\n", emu->memhdr->nblocks);
     55        } else {
     56                snd_iprintf(buf, "Memory Size: 0\n");
     57        }
     58        if (emu->sflist) {
     59                down(&emu->sflist->presets_mutex);
     60                snd_iprintf(buf, "SoundFonts: %d\n", emu->sflist->fonts_size);
     61                snd_iprintf(buf, "Instruments: %d\n", emu->sflist->zone_counter);
     62                snd_iprintf(buf, "Samples: %d\n", emu->sflist->sample_counter);
     63                snd_iprintf(buf, "Locked Instruments: %d\n", emu->sflist->zone_locked);
     64                snd_iprintf(buf, "Locked Samples: %d\n", emu->sflist->sample_locked);
     65                up(&emu->sflist->presets_mutex);
     66        }
    6867#if 0  /* debug */
    69     if (emu->voices[0].state != SNDRV_EMUX_ST_OFF && emu->voices[0].ch >= 0) {
    70         snd_emux_voice_t *vp = &emu->voices[0];
    71         snd_iprintf(buf, "voice 0: on\n");
    72         snd_iprintf(buf, "mod delay=%x, atkhld=%x, dcysus=%x, rel=%x\n",
    73                     vp->reg.parm.moddelay,
    74                     vp->reg.parm.modatkhld,
    75                     vp->reg.parm.moddcysus,
    76                     vp->reg.parm.modrelease);
    77         snd_iprintf(buf, "vol delay=%x, atkhld=%x, dcysus=%x, rel=%x\n",
    78                     vp->reg.parm.voldelay,
    79                     vp->reg.parm.volatkhld,
    80                     vp->reg.parm.voldcysus,
    81                     vp->reg.parm.volrelease);
    82         snd_iprintf(buf, "lfo1 delay=%x, lfo2 delay=%x, pefe=%x\n",
    83                     vp->reg.parm.lfo1delay,
    84                     vp->reg.parm.lfo2delay,
    85                     vp->reg.parm.pefe);
    86         snd_iprintf(buf, "fmmod=%x, tremfrq=%x, fm2frq2=%x\n",
    87                     vp->reg.parm.fmmod,
    88                     vp->reg.parm.tremfrq,
    89                     vp->reg.parm.fm2frq2);
    90         snd_iprintf(buf, "cutoff=%x, filterQ=%x, chorus=%x, reverb=%x\n",
    91                     vp->reg.parm.cutoff,
    92                     vp->reg.parm.filterQ,
    93                     vp->reg.parm.chorus,
    94                     vp->reg.parm.reverb);
    95         snd_iprintf(buf, "avol=%x, acutoff=%x, apitch=%x\n",
    96                     vp->avol, vp->acutoff, vp->apitch);
    97         snd_iprintf(buf, "apan=%x, aaux=%x, ptarget=%x, vtarget=%x, ftarget=%x\n",
    98                     vp->apan, vp->aaux,
    99                     vp->ptarget,
    100                     vp->vtarget,
    101                     vp->ftarget);
    102         snd_iprintf(buf, "start=%x, end=%x, loopstart=%x, loopend=%x\n",
    103                     vp->reg.start, vp->reg.end, vp->reg.loopstart, vp->reg.loopend);
    104         snd_iprintf(buf, "sample_mode=%x, rate=%x\n", vp->reg.sample_mode, vp->reg.rate_offset);
    105     }
     68        if (emu->voices[0].state != SNDRV_EMUX_ST_OFF && emu->voices[0].ch >= 0) {
     69                struct snd_emux_voice *vp = &emu->voices[0];
     70                snd_iprintf(buf, "voice 0: on\n");
     71                snd_iprintf(buf, "mod delay=%x, atkhld=%x, dcysus=%x, rel=%x\n",
     72                            vp->reg.parm.moddelay,
     73                            vp->reg.parm.modatkhld,
     74                            vp->reg.parm.moddcysus,
     75                            vp->reg.parm.modrelease);
     76                snd_iprintf(buf, "vol delay=%x, atkhld=%x, dcysus=%x, rel=%x\n",
     77                            vp->reg.parm.voldelay,
     78                            vp->reg.parm.volatkhld,
     79                            vp->reg.parm.voldcysus,
     80                            vp->reg.parm.volrelease);
     81                snd_iprintf(buf, "lfo1 delay=%x, lfo2 delay=%x, pefe=%x\n",
     82                            vp->reg.parm.lfo1delay,
     83                            vp->reg.parm.lfo2delay,
     84                            vp->reg.parm.pefe);
     85                snd_iprintf(buf, "fmmod=%x, tremfrq=%x, fm2frq2=%x\n",
     86                            vp->reg.parm.fmmod,
     87                            vp->reg.parm.tremfrq,
     88                            vp->reg.parm.fm2frq2);
     89                snd_iprintf(buf, "cutoff=%x, filterQ=%x, chorus=%x, reverb=%x\n",
     90                            vp->reg.parm.cutoff,
     91                            vp->reg.parm.filterQ,
     92                            vp->reg.parm.chorus,
     93                            vp->reg.parm.reverb);
     94                snd_iprintf(buf, "avol=%x, acutoff=%x, apitch=%x\n",
     95                            vp->avol, vp->acutoff, vp->apitch);
     96                snd_iprintf(buf, "apan=%x, aaux=%x, ptarget=%x, vtarget=%x, ftarget=%x\n",
     97                            vp->apan, vp->aaux,
     98                            vp->ptarget,
     99                            vp->vtarget,
     100                            vp->ftarget);
     101                snd_iprintf(buf, "start=%x, end=%x, loopstart=%x, loopend=%x\n",
     102                            vp->reg.start, vp->reg.end, vp->reg.loopstart, vp->reg.loopend);
     103                snd_iprintf(buf, "sample_mode=%x, rate=%x\n", vp->reg.sample_mode, vp->reg.rate_offset);
     104        }
    106105#endif
    107     up(&emu->register_mutex);
     106        up(&emu->register_mutex);
    108107}
    109108
    110109
    111 void snd_emux_proc_init(snd_emux_t *emu, snd_card_t *card, int device)
     110void snd_emux_proc_init(struct snd_emux *emu, struct snd_card *card, int device)
    112111{
    113     snd_info_entry_t *entry;
    114     char name[64];
     112        struct snd_info_entry *entry;
     113        char name[64];
    115114
    116     sprintf(name, "wavetableD%d", device);
    117     entry = snd_info_create_card_entry(card, name, card->proc_root);
    118     if (entry == NULL)
    119         return;
     115        sprintf(name, "wavetableD%d", device);
     116        entry = snd_info_create_card_entry(card, name, card->proc_root);
     117        if (entry == NULL)
     118                return;
    120119
    121     entry->content = SNDRV_INFO_CONTENT_TEXT;
    122     entry->private_data = emu;
    123     entry->c.text.read_size = 1024;
    124     entry->c.text.read = snd_emux_proc_info_read;
    125     if (snd_info_register(entry) < 0)
    126         snd_info_free_entry(entry);
    127     else
    128         emu->proc = entry;
     120        entry->content = SNDRV_INFO_CONTENT_TEXT;
     121        entry->private_data = emu;
     122        entry->c.text.read_size = 1024;
     123        entry->c.text.read = snd_emux_proc_info_read;
     124        if (snd_info_register(entry) < 0)
     125                snd_info_free_entry(entry);
     126        else
     127                emu->proc = entry;
    129128}
    130129
    131 void snd_emux_proc_free(snd_emux_t *emu)
     130void snd_emux_proc_free(struct snd_emux *emu)
    132131{
    133     if (emu->proc) {
    134         snd_info_unregister(emu->proc);
    135         emu->proc = NULL;
    136     }
     132        if (emu->proc) {
     133                snd_info_unregister(emu->proc);
     134                emu->proc = NULL;
     135        }
    137136}
    138137
  • GPL/trunk/alsa-kernel/synth/emux/emux_seq.c

    r33 r34  
    2020 */
    2121
    22 #define __NO_VERSION__
    2322#include "emux_voice.h"
    2423#include <linux/slab.h>
     
    2726/* Prototypes for static functions */
    2827static void free_port(void *private);
    29 static void snd_emux_init_port(snd_emux_port_t *p);
    30 static int snd_emux_use(void *private_data, snd_seq_port_subscribe_t *info);
    31 static int snd_emux_unuse(void *private_data, snd_seq_port_subscribe_t *info);
    32 static int get_client(snd_card_t *card, int index, char *name);
     28static void snd_emux_init_port(struct snd_emux_port *p);
     29static int snd_emux_use(void *private_data, struct snd_seq_port_subscribe *info);
     30static int snd_emux_unuse(void *private_data, struct snd_seq_port_subscribe *info);
     31static int get_client(struct snd_card *card, int index, char *name);
    3332
    3433/*
    3534 * MIDI emulation operators
    3635 */
    37 static snd_midi_op_t emux_ops = {
    38     snd_emux_note_on,
    39     snd_emux_note_off,
    40     snd_emux_key_press,
    41     snd_emux_terminate_note,
    42     snd_emux_control,
    43     snd_emux_nrpn,
    44     snd_emux_sysex,
     36static struct snd_midi_op emux_ops = {
     37        snd_emux_note_on,
     38        snd_emux_note_off,
     39        snd_emux_key_press,
     40        snd_emux_terminate_note,
     41        snd_emux_control,
     42        snd_emux_nrpn,
     43        snd_emux_sysex,
    4544};
    4645
     
    5554 */
    5655#define DEFAULT_MIDI_TYPE       (SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC |\
    57     SNDRV_SEQ_PORT_TYPE_MIDI_GM |\
    58     SNDRV_SEQ_PORT_TYPE_MIDI_GS |\
    59     SNDRV_SEQ_PORT_TYPE_MIDI_XG |\
    60     SNDRV_SEQ_PORT_TYPE_DIRECT_SAMPLE)
    61 
    62 /*
    63  */
    64 #ifndef TARGET_OS2
    65 static inline void dec_mod_count(struct module *module)
    66 {
    67     if (module)
    68         __MOD_DEC_USE_COUNT(module);
    69 }
    70 #endif
     56                                 SNDRV_SEQ_PORT_TYPE_MIDI_GM |\
     57                                 SNDRV_SEQ_PORT_TYPE_MIDI_GS |\
     58                                 SNDRV_SEQ_PORT_TYPE_MIDI_XG |\
     59                                 SNDRV_SEQ_PORT_TYPE_DIRECT_SAMPLE)
     60
    7161/*
    7262 * Initialise the EMUX Synth by creating a client and registering
     
    7666 */
    7767int
    78 snd_emux_init_seq(snd_emux_t *emu, snd_card_t *card, int index)
    79 {
    80     int  i;
    81     snd_seq_port_callback_t pinfo;
    82     char tmpname[64];
    83 
    84     sprintf(tmpname, "%s WaveTable", emu->name);
    85     emu->client = get_client(card, index, tmpname);
    86     if (emu->client < 0) {
    87         snd_printk("can't create client\n");
    88         return -ENODEV;
    89     }
    90 
    91     if (emu->num_ports < 0) {
    92         snd_printk("seqports must be greater than zero\n");
    93         emu->num_ports = 1;
    94     } else if (emu->num_ports >= SNDRV_EMUX_MAX_PORTS) {
    95         snd_printk("too many ports."
    96                    "limited max. ports %d\n", SNDRV_EMUX_MAX_PORTS);
    97         emu->num_ports = SNDRV_EMUX_MAX_PORTS;
    98     }
    99 
    100     memset(&pinfo, 0, sizeof(pinfo));
    101     pinfo.owner = THIS_MODULE;
    102     pinfo.use = snd_emux_use;
    103     pinfo.unuse = snd_emux_unuse;
    104     pinfo.event_input = snd_emux_event_input;
    105 
    106     for (i = 0; i < emu->num_ports; i++) {
    107         snd_emux_port_t *p;
    108 
    109         sprintf(tmpname, "%s Port %d", emu->name, i);
    110         p = snd_emux_create_port(emu, tmpname, MIDI_CHANNELS,
    111                                  0, &pinfo);
    112         if (p == NULL) {
    113             snd_printk("can't create port\n");
    114             return -ENOMEM;
    115         }
    116 
    117         p->port_mode =  SNDRV_EMUX_PORT_MODE_MIDI;
    118         snd_emux_init_port(p);
    119         emu->ports[i] = p->chset.port;
    120     }
    121 
    122     return 0;
     68snd_emux_init_seq(struct snd_emux *emu, struct snd_card *card, int index)
     69{
     70        int  i;
     71        struct snd_seq_port_callback pinfo;
     72        char tmpname[64];
     73
     74        sprintf(tmpname, "%s WaveTable", emu->name);
     75        emu->client = get_client(card, index, tmpname);
     76        if (emu->client < 0) {
     77                snd_printk("can't create client\n");
     78                return -ENODEV;
     79        }
     80
     81        if (emu->num_ports < 0) {
     82                snd_printk("seqports must be greater than zero\n");
     83                emu->num_ports = 1;
     84        } else if (emu->num_ports >= SNDRV_EMUX_MAX_PORTS) {
     85                snd_printk("too many ports."
     86                           "limited max. ports %d\n", SNDRV_EMUX_MAX_PORTS);
     87                emu->num_ports = SNDRV_EMUX_MAX_PORTS;
     88        }
     89
     90        memset(&pinfo, 0, sizeof(pinfo));
     91        pinfo.owner = THIS_MODULE;
     92        pinfo.use = snd_emux_use;
     93        pinfo.unuse = snd_emux_unuse;
     94        pinfo.event_input = snd_emux_event_input;
     95
     96        for (i = 0; i < emu->num_ports; i++) {
     97                struct snd_emux_port *p;
     98
     99                sprintf(tmpname, "%s Port %d", emu->name, i);
     100                p = snd_emux_create_port(emu, tmpname, MIDI_CHANNELS,
     101                                         0, &pinfo);
     102                if (p == NULL) {
     103                        snd_printk("can't create port\n");
     104                        return -ENOMEM;
     105                }
     106
     107                p->port_mode =  SNDRV_EMUX_PORT_MODE_MIDI;
     108                snd_emux_init_port(p);
     109                emu->ports[i] = p->chset.port;
     110                emu->portptrs[i] = p;
     111        }
     112
     113        return 0;
    123114}
    124115
     
    129120 */
    130121void
    131 snd_emux_detach_seq(snd_emux_t *emu)
    132 {
    133     if (emu->voices)
    134         snd_emux_terminate_all(emu);
    135 
    136     down(&emu->register_mutex);
    137     if (emu->client >= 0) {
    138         snd_seq_delete_kernel_client(emu->client);
    139         emu->client = -1;
    140     }
    141     up(&emu->register_mutex);
     122snd_emux_detach_seq(struct snd_emux *emu)
     123{
     124        if (emu->voices)
     125                snd_emux_terminate_all(emu);
     126               
     127        down(&emu->register_mutex);
     128        if (emu->client >= 0) {
     129                snd_seq_delete_kernel_client(emu->client);
     130                emu->client = -1;
     131        }
     132        up(&emu->register_mutex);
    142133}
    143134
     
    147138 */
    148139
    149 snd_emux_port_t *
    150 snd_emux_create_port(snd_emux_t *emu, char *name,
    151                      int max_channels, int oss_port,
    152                      snd_seq_port_callback_t *callback)
    153 {
    154     snd_emux_port_t *p;
    155     int i, type, cap;
    156 
    157     /* Allocate structures for this channel */
    158     if ((p = kcalloc(1, sizeof(*p), GFP_KERNEL)) == NULL) {
    159         snd_printk("no memory\n");
    160         return NULL;
    161     }
    162     p->chset.channels = kcalloc(max_channels, sizeof(snd_midi_channel_t), GFP_KERNEL);
    163     if (p->chset.channels == NULL) {
    164         snd_printk("no memory\n");
    165         kfree(p);
    166         return NULL;
    167     }
    168     for (i = 0; i < max_channels; i++)
    169         p->chset.channels[i].number = i;
    170     p->chset.private_data = p;
    171     p->chset.max_channels = max_channels;
    172     p->emu = emu;
    173     p->chset.client = emu->client;
     140struct snd_emux_port *
     141snd_emux_create_port(struct snd_emux *emu, char *name,
     142                     int max_channels, int oss_port,
     143                     struct snd_seq_port_callback *callback)
     144{
     145        struct snd_emux_port *p;
     146        int i, type, cap;
     147
     148        /* Allocate structures for this channel */
     149        if ((p = kzalloc(sizeof(*p), GFP_KERNEL)) == NULL) {
     150                snd_printk("no memory\n");
     151                return NULL;
     152        }
     153        p->chset.channels = kcalloc(max_channels, sizeof(struct snd_midi_channel), GFP_KERNEL);
     154        if (p->chset.channels == NULL) {
     155                snd_printk("no memory\n");
     156                kfree(p);
     157                return NULL;
     158        }
     159        for (i = 0; i < max_channels; i++)
     160                p->chset.channels[i].number = i;
     161        p->chset.private_data = p;
     162        p->chset.max_channels = max_channels;
     163        p->emu = emu;
     164        p->chset.client = emu->client;
    174165#ifdef SNDRV_EMUX_USE_RAW_EFFECT
    175     snd_emux_create_effect(p);
     166        snd_emux_create_effect(p);
    176167#endif
    177     callback->private_free = free_port;
    178     callback->private_data = p;
    179 
    180     cap = SNDRV_SEQ_PORT_CAP_WRITE;
    181     if (oss_port) {
    182         type = SNDRV_SEQ_PORT_TYPE_SPECIFIC;
    183     } else {
    184         type = DEFAULT_MIDI_TYPE;
    185         cap |= SNDRV_SEQ_PORT_CAP_SUBS_WRITE;
    186     }
    187 
    188     p->chset.port = snd_seq_event_port_attach(emu->client, callback,
    189                                               cap, type, max_channels,
    190                                               emu->max_voices, name);
    191 
    192     return p;
     168        callback->private_free = free_port;
     169        callback->private_data = p;
     170
     171        cap = SNDRV_SEQ_PORT_CAP_WRITE;
     172        if (oss_port) {
     173                type = SNDRV_SEQ_PORT_TYPE_SPECIFIC;
     174        } else {
     175                type = DEFAULT_MIDI_TYPE;
     176                cap |= SNDRV_SEQ_PORT_CAP_SUBS_WRITE;
     177        }
     178
     179        p->chset.port = snd_seq_event_port_attach(emu->client, callback,
     180                                                  cap, type, max_channels,
     181                                                  emu->max_voices, name);
     182
     183        return p;
    193184}
    194185
     
    200191free_port(void *private_data)
    201192{
    202     snd_emux_port_t *p;
    203 
    204     p = private_data;
    205     if (p) {
     193        struct snd_emux_port *p;
     194
     195        p = private_data;
     196        if (p) {
    206197#ifdef SNDRV_EMUX_USE_RAW_EFFECT
    207         snd_emux_delete_effect(p);
     198                snd_emux_delete_effect(p);
    208199#endif
    209         if (p->chset.channels)
    210             kfree(p->chset.channels);
    211         kfree(p);
    212     }
     200                kfree(p->chset.channels);
     201                kfree(p);
     202        }
    213203}
    214204
     
    220210 */
    221211static void
    222 snd_emux_init_port(snd_emux_port_t *p)
    223 {
    224     p->drum_flags = DEFAULT_DRUM_FLAGS;
    225     p->volume_atten = 0;
    226 
    227     snd_emux_reset_port(p);
     212snd_emux_init_port(struct snd_emux_port *p)
     213{
     214        p->drum_flags = DEFAULT_DRUM_FLAGS;
     215        p->volume_atten = 0;
     216
     217        snd_emux_reset_port(p);
    228218}
    229219
     
    233223 */
    234224void
    235 snd_emux_reset_port(snd_emux_port_t *port)
    236 {
    237     int i;
    238 
    239     /* stop all sounds */
    240     snd_emux_sounds_off_all(port);
    241 
    242     snd_midi_channel_set_clear(&port->chset);
     225snd_emux_reset_port(struct snd_emux_port *port)
     226{
     227        int i;
     228
     229        /* stop all sounds */
     230        snd_emux_sounds_off_all(port);
     231
     232        snd_midi_channel_set_clear(&port->chset);
    243233
    244234#ifdef SNDRV_EMUX_USE_RAW_EFFECT
    245     snd_emux_clear_effect(port);
     235        snd_emux_clear_effect(port);
    246236#endif
    247237
    248     /* set port specific control parameters */
    249     port->ctrls[EMUX_MD_DEF_BANK] = 0;
    250     port->ctrls[EMUX_MD_DEF_DRUM] = 0;
    251     port->ctrls[EMUX_MD_REALTIME_PAN] = 1;
    252 
    253     for (i = 0; i < port->chset.max_channels; i++) {
    254         snd_midi_channel_t *chan = port->chset.channels + i;
    255         chan->drum_channel = ((port->drum_flags >> i) & 1) ? 1 : 0;
    256     }
     238        /* set port specific control parameters */
     239        port->ctrls[EMUX_MD_DEF_BANK] = 0;
     240        port->ctrls[EMUX_MD_DEF_DRUM] = 0;
     241        port->ctrls[EMUX_MD_REALTIME_PAN] = 1;
     242
     243        for (i = 0; i < port->chset.max_channels; i++) {
     244                struct snd_midi_channel *chan = port->chset.channels + i;
     245                chan->drum_channel = ((port->drum_flags >> i) & 1) ? 1 : 0;
     246        }
    257247}
    258248
     
    262252 */
    263253int
    264 snd_emux_event_input(snd_seq_event_t *ev, int direct, void *private_data,
    265                      int atomic, int hop)
    266 {
    267     snd_emux_port_t *port;
    268 
    269     port = private_data;
    270     snd_assert(port != NULL && ev != NULL, return -EINVAL);
    271 
    272     snd_midi_process_event(&emux_ops, ev, &port->chset);
    273 
    274     return 0;
     254snd_emux_event_input(struct snd_seq_event *ev, int direct, void *private_data,
     255                     int atomic, int hop)
     256{
     257        struct snd_emux_port *port;
     258
     259        port = private_data;
     260        snd_assert(port != NULL && ev != NULL, return -EINVAL);
     261
     262        snd_midi_process_event(&emux_ops, ev, &port->chset);
     263
     264        return 0;
    275265}
    276266
     
    280270 */
    281271int
    282 snd_emux_inc_count(snd_emux_t *emu)
    283 {
    284     emu->used++;
    285     if (!try_inc_mod_count(emu->ops.owner))
    286         goto __error;
    287     if (!try_inc_mod_count(emu->card->module)) {
    288         dec_mod_count(emu->ops.owner);
    289     __error:
    290         emu->used--;
    291         return 0;
    292     }
    293     return 1;
     272snd_emux_inc_count(struct snd_emux *emu)
     273{
     274        emu->used++;
     275        if (!try_module_get(emu->ops.owner))
     276                goto __error;
     277        if (!try_module_get(emu->card->module)) {
     278                module_put(emu->ops.owner);
     279              __error:
     280                emu->used--;
     281                return 0;
     282        }
     283        return 1;
    294284}
    295285
     
    299289 */
    300290void
    301 snd_emux_dec_count(snd_emux_t *emu)
    302 {
    303     dec_mod_count(emu->ops.owner);
    304     emu->used--;
    305     if (emu->used <= 0)
    306         snd_emux_terminate_all(emu);
    307     dec_mod_count(emu->card->module);
     291snd_emux_dec_count(struct snd_emux *emu)
     292{
     293        module_put(emu->card->module);
     294        emu->used--;
     295        if (emu->used <= 0)
     296                snd_emux_terminate_all(emu);
     297        module_put(emu->ops.owner);
    308298}
    309299
     
    313303 */
    314304static int
    315 snd_emux_use(void *private_data, snd_seq_port_subscribe_t *info)
    316 {
    317     snd_emux_port_t *p;
    318     snd_emux_t *emu;
    319 
    320     p = private_data;
    321     snd_assert(p != NULL, return -EINVAL);
    322     emu = p->emu;
    323     snd_assert(emu != NULL, return -EINVAL);
    324 
    325     down(&emu->register_mutex);
    326     snd_emux_init_port(p);
    327     snd_emux_inc_count(emu);
    328     up(&emu->register_mutex);
    329     return 0;
     305snd_emux_use(void *private_data, struct snd_seq_port_subscribe *info)
     306{
     307        struct snd_emux_port *p;
     308        struct snd_emux *emu;
     309
     310        p = private_data;
     311        snd_assert(p != NULL, return -EINVAL);
     312        emu = p->emu;
     313        snd_assert(emu != NULL, return -EINVAL);
     314
     315        down(&emu->register_mutex);
     316        snd_emux_init_port(p);
     317        snd_emux_inc_count(emu);
     318        up(&emu->register_mutex);
     319        return 0;
    330320}
    331321
     
    334324 */
    335325static int
    336 snd_emux_unuse(void *private_data, snd_seq_port_subscribe_t *info)
    337 {
    338     snd_emux_port_t *p;
    339     snd_emux_t *emu;
    340 
    341     p = private_data;
    342     snd_assert(p != NULL, return -EINVAL);
    343     emu = p->emu;
    344     snd_assert(emu != NULL, return -EINVAL);
    345 
    346     down(&emu->register_mutex);
    347     snd_emux_sounds_off_all(p);
    348     snd_emux_dec_count(emu);
    349     up(&emu->register_mutex);
    350     return 0;
     326snd_emux_unuse(void *private_data, struct snd_seq_port_subscribe *info)
     327{
     328        struct snd_emux_port *p;
     329        struct snd_emux *emu;
     330
     331        p = private_data;
     332        snd_assert(p != NULL, return -EINVAL);
     333        emu = p->emu;
     334        snd_assert(emu != NULL, return -EINVAL);
     335
     336        down(&emu->register_mutex);
     337        snd_emux_sounds_off_all(p);
     338        snd_emux_dec_count(emu);
     339        up(&emu->register_mutex);
     340        return 0;
    351341}
    352342
     
    356346 */
    357347static int
    358 get_client(snd_card_t *card, int index, char *name)
    359 {
    360     snd_seq_client_callback_t callbacks;
    361     snd_seq_client_info_t cinfo;
    362     int client;
    363 
    364     memset(&callbacks, 0, sizeof(callbacks));
    365     callbacks.private_data = NULL;
    366     callbacks.allow_input = 1;
    367     callbacks.allow_output = 1;
    368 
    369     /* Find a free client, start from 1 as the MPU expects to use 0 */
    370     client = snd_seq_create_kernel_client(card, index, &callbacks);
    371     if (client < 0)
    372         return client;
    373 
    374     memset(&cinfo, 0, sizeof(cinfo));
    375     cinfo.client = client;
    376     cinfo.type = KERNEL_CLIENT;
    377     strcpy(cinfo.name, name);
    378     snd_seq_kernel_client_ctl(client, SNDRV_SEQ_IOCTL_SET_CLIENT_INFO, &cinfo);
    379 
    380     return client;
     348get_client(struct snd_card *card, int index, char *name)
     349{
     350        struct snd_seq_client_callback callbacks;
     351        struct snd_seq_client_info cinfo;
     352        int client;
     353
     354        memset(&callbacks, 0, sizeof(callbacks));
     355        callbacks.private_data = NULL;
     356        callbacks.allow_input = 1;
     357        callbacks.allow_output = 1;
     358
     359        /* Find a free client, start from 1 as the MPU expects to use 0 */
     360        client = snd_seq_create_kernel_client(card, index, &callbacks);
     361        if (client < 0)
     362                return client;
     363
     364        memset(&cinfo, 0, sizeof(cinfo));
     365        cinfo.client = client;
     366        cinfo.type = KERNEL_CLIENT;
     367        strcpy(cinfo.name, name);
     368        snd_seq_kernel_client_ctl(client, SNDRV_SEQ_IOCTL_SET_CLIENT_INFO, &cinfo);
     369
     370        return client;
    381371}
    382372
     
    385375 * attach virtual rawmidi devices
    386376 */
    387 int snd_emux_init_virmidi(snd_emux_t *emu, snd_card_t *card)
    388 {
    389     int i;
    390 
    391     emu->vmidi = NULL;
    392     if (emu->midi_ports <= 0)
    393         return 0;
    394 
    395     emu->vmidi = kcalloc(emu->midi_ports, sizeof(snd_rawmidi_t*), GFP_KERNEL);
    396     if (emu->vmidi == NULL)
    397         return -ENOMEM;
    398 
    399     for (i = 0; i < emu->midi_ports; i++) {
    400         snd_rawmidi_t *rmidi;
    401         snd_virmidi_dev_t *rdev;
    402         if (snd_virmidi_new(card, emu->midi_devidx + i, &rmidi) < 0)
    403             goto __error;
    404         rdev = rmidi->private_data;
    405         sprintf(rmidi->name, "%s Synth MIDI", emu->name);
    406         rdev->seq_mode = SNDRV_VIRMIDI_SEQ_ATTACH;
    407         rdev->client = emu->client;
    408         rdev->port = emu->ports[i];
    409         if (snd_device_register(card, rmidi) < 0) {
    410             snd_device_free(card, rmidi);
    411             goto __error;
    412         }
    413         emu->vmidi[i] = rmidi;
    414         //snd_printk("virmidi %d ok\n", i);
    415     }
    416     return 0;
     377int snd_emux_init_virmidi(struct snd_emux *emu, struct snd_card *card)
     378{
     379        int i;
     380
     381        emu->vmidi = NULL;
     382        if (emu->midi_ports <= 0)
     383                return 0;
     384
     385        emu->vmidi = kcalloc(emu->midi_ports, sizeof(struct snd_rawmidi *), GFP_KERNEL);
     386        if (emu->vmidi == NULL)
     387                return -ENOMEM;
     388
     389        for (i = 0; i < emu->midi_ports; i++) {
     390                struct snd_rawmidi *rmidi;
     391                struct snd_virmidi_dev *rdev;
     392                if (snd_virmidi_new(card, emu->midi_devidx + i, &rmidi) < 0)
     393                        goto __error;
     394                rdev = rmidi->private_data;
     395                sprintf(rmidi->name, "%s Synth MIDI", emu->name);
     396                rdev->seq_mode = SNDRV_VIRMIDI_SEQ_ATTACH;
     397                rdev->client = emu->client;
     398                rdev->port = emu->ports[i];
     399                if (snd_device_register(card, rmidi) < 0) {
     400                        snd_device_free(card, rmidi);
     401                        goto __error;
     402                }
     403                emu->vmidi[i] = rmidi;
     404                //snd_printk("virmidi %d ok\n", i);
     405        }
     406        return 0;
    417407
    418408__error:
    419     //snd_printk("error init..\n");
    420     snd_emux_delete_virmidi(emu);
    421     return -ENOMEM;
    422 }
    423 
    424 int snd_emux_delete_virmidi(snd_emux_t *emu)
    425 {
    426     int i;
    427 
    428     if (emu->vmidi == NULL)
    429         return 0;
    430 
    431     for (i = 0; i < emu->midi_ports; i++) {
    432         if (emu->vmidi[i])
    433             snd_device_free(emu->card, emu->vmidi[i]);
    434     }
    435     kfree(emu->vmidi);
    436     emu->vmidi = NULL;
    437     return 0;
    438 }
     409        //snd_printk("error init..\n");
     410        snd_emux_delete_virmidi(emu);
     411        return -ENOMEM;
     412}
     413
     414int snd_emux_delete_virmidi(struct snd_emux *emu)
     415{
     416        int i;
     417
     418        if (emu->vmidi == NULL)
     419                return 0;
     420
     421        for (i = 0; i < emu->midi_ports; i++) {
     422                if (emu->vmidi[i])
     423                        snd_device_free(emu->card, emu->vmidi[i]);
     424        }
     425        kfree(emu->vmidi);
     426        emu->vmidi = NULL;
     427        return 0;
     428}
  • GPL/trunk/alsa-kernel/synth/emux/emux_synth.c

    r33 r34  
    2323 */
    2424
    25 #define __NO_VERSION__
    2625#include "emux_voice.h"
    2726#include <sound/asoundef.h>
     
    3837#define LIMITMAX(x, a) do {if ((x) > (a)) (x) = (a); } while (0)
    3938
    40 static int get_zone(snd_emux_t *emu, snd_emux_port_t *port, int *notep, int vel, snd_midi_channel_t *chan, snd_sf_zone_t **table);
    41 static int get_bank(snd_emux_port_t *port, snd_midi_channel_t *chan);
    42 static void terminate_note1(snd_emux_t *emu, int note, snd_midi_channel_t *chan, int free);
    43 static void exclusive_note_off(snd_emux_t *emu, snd_emux_port_t *port, int exclass);
    44 static void terminate_voice(snd_emux_t *emu, snd_emux_voice_t *vp, int free);
    45 static void update_voice(snd_emux_t *emu, snd_emux_voice_t *vp, int update);
    46 static void setup_voice(snd_emux_voice_t *vp);
    47 static int calc_pan(snd_emux_voice_t *vp);
    48 static int calc_volume(snd_emux_voice_t *vp);
    49 static int calc_pitch(snd_emux_voice_t *vp);
     39static int get_zone(struct snd_emux *emu, struct snd_emux_port *port,
     40                    int *notep, int vel, struct snd_midi_channel *chan,
     41                    struct snd_sf_zone **table);
     42static int get_bank(struct snd_emux_port *port, struct snd_midi_channel *chan);
     43static void terminate_note1(struct snd_emux *emu, int note,
     44                            struct snd_midi_channel *chan, int free);
     45static void exclusive_note_off(struct snd_emux *emu, struct snd_emux_port *port,
     46                               int exclass);
     47static void terminate_voice(struct snd_emux *emu, struct snd_emux_voice *vp, int free);
     48static void update_voice(struct snd_emux *emu, struct snd_emux_voice *vp, int update);
     49static void setup_voice(struct snd_emux_voice *vp);
     50static int calc_pan(struct snd_emux_voice *vp);
     51static int calc_volume(struct snd_emux_voice *vp);
     52static int calc_pitch(struct snd_emux_voice *vp);
    5053
    5154
     
    5457 */
    5558void
    56     snd_emux_note_on(void *p, int note, int vel, snd_midi_channel_t *chan)
    57 {
    58     snd_emux_t *emu;
    59     int i, key, nvoices;
    60     snd_emux_voice_t *vp;
    61     snd_sf_zone_t *table[SNDRV_EMUX_MAX_MULTI_VOICES];
    62     unsigned long flags;
    63     snd_emux_port_t *port;
    64 
    65     port = p;
    66     snd_assert(port != NULL && chan != NULL, return);
    67 
    68     emu = port->emu;
    69     snd_assert(emu != NULL, return);
    70     snd_assert(emu->ops.get_voice != NULL, return);
    71     snd_assert(emu->ops.trigger != NULL, return);
    72 
    73     key = note; /* remember the original note */
    74     nvoices = get_zone(emu, port, &note, vel, chan, table);
    75     if (! nvoices)
    76         return;
    77 
    78     /* exclusive note off */
    79     for (i = 0; i < nvoices; i++) {
    80         snd_sf_zone_t *zp = table[i];
    81         if (zp && zp->v.exclusiveClass)
    82             exclusive_note_off(emu, port, zp->v.exclusiveClass);
    83     }
     59snd_emux_note_on(void *p, int note, int vel, struct snd_midi_channel *chan)
     60{
     61        struct snd_emux *emu;
     62        int i, key, nvoices;
     63        struct snd_emux_voice *vp;
     64        struct snd_sf_zone *table[SNDRV_EMUX_MAX_MULTI_VOICES];
     65        unsigned long flags;
     66        struct snd_emux_port *port;
     67
     68        port = p;
     69        snd_assert(port != NULL && chan != NULL, return);
     70
     71        emu = port->emu;
     72        snd_assert(emu != NULL, return);
     73        snd_assert(emu->ops.get_voice != NULL, return);
     74        snd_assert(emu->ops.trigger != NULL, return);
     75
     76        key = note; /* remember the original note */
     77        nvoices = get_zone(emu, port, &note, vel, chan, table);
     78        if (! nvoices)
     79                return;
     80
     81        /* exclusive note off */
     82        for (i = 0; i < nvoices; i++) {
     83                struct snd_sf_zone *zp = table[i];
     84                if (zp && zp->v.exclusiveClass)
     85                        exclusive_note_off(emu, port, zp->v.exclusiveClass);
     86        }
    8487
    8588#if 0 // seems not necessary
    86     /* Turn off the same note on the same channel. */
    87     terminate_note1(emu, key, chan, 0);
     89        /* Turn off the same note on the same channel. */
     90        terminate_note1(emu, key, chan, 0);
    8891#endif
    8992
    90     spin_lock_irqsave(&emu->voice_lock, flags);
    91     for (i = 0; i < nvoices; i++) {
    92 
    93         /* set up each voice parameter */
    94         /* at this stage, we don't trigger the voice yet. */
    95 
    96         if (table[i] == NULL)
    97             continue;
    98 
    99         vp = emu->ops.get_voice(emu, port);
    100         if (vp == NULL || vp->ch < 0)
    101             continue;
    102         snd_assert(vp->emu != NULL && vp->hw != NULL, return);
    103         if (STATE_IS_PLAYING(vp->state))
    104             emu->ops.terminate(vp);
    105 
    106         vp->time = emu->use_time++;
    107         vp->chan = chan;
    108         vp->port = port;
    109         vp->key = key;
    110         vp->note = note;
    111         vp->velocity = vel;
    112         vp->zone = table[i];
    113         if (vp->zone->sample)
    114             vp->block = vp->zone->sample->block;
    115         else
    116             vp->block = NULL;
    117 
    118         setup_voice(vp);
    119 
    120         vp->state = SNDRV_EMUX_ST_STANDBY;
    121         if (emu->ops.prepare) {
    122             vp->state = SNDRV_EMUX_ST_OFF;
    123             if (emu->ops.prepare(vp) >= 0)
    124                 vp->state = SNDRV_EMUX_ST_STANDBY;
    125         }
    126     }
    127 
    128     /* start envelope now */
    129     for (i = 0; i < emu->max_voices; i++) {
    130         vp = &emu->voices[i];
    131         if (vp->state == SNDRV_EMUX_ST_STANDBY &&
    132             vp->chan == chan) {
    133             emu->ops.trigger(vp);
    134             vp->state = SNDRV_EMUX_ST_ON;
    135             vp->ontime = jiffies; /* remember the trigger timing */
    136         }
    137     }
    138     spin_unlock_irqrestore(&emu->voice_lock, flags);
     93        spin_lock_irqsave(&emu->voice_lock, flags);
     94        for (i = 0; i < nvoices; i++) {
     95
     96                /* set up each voice parameter */
     97                /* at this stage, we don't trigger the voice yet. */
     98
     99                if (table[i] == NULL)
     100                        continue;
     101
     102                vp = emu->ops.get_voice(emu, port);
     103                if (vp == NULL || vp->ch < 0)
     104                        continue;
     105                if (STATE_IS_PLAYING(vp->state))
     106                        emu->ops.terminate(vp);
     107
     108                vp->time = emu->use_time++;
     109                vp->chan = chan;
     110                vp->port = port;
     111                vp->key = key;
     112                vp->note = note;
     113                vp->velocity = vel;
     114                vp->zone = table[i];
     115                if (vp->zone->sample)
     116                        vp->block = vp->zone->sample->block;
     117                else
     118                        vp->block = NULL;
     119
     120                setup_voice(vp);
     121
     122                vp->state = SNDRV_EMUX_ST_STANDBY;
     123                if (emu->ops.prepare) {
     124                        vp->state = SNDRV_EMUX_ST_OFF;
     125                        if (emu->ops.prepare(vp) >= 0)
     126                                vp->state = SNDRV_EMUX_ST_STANDBY;
     127                }
     128        }
     129
     130        /* start envelope now */
     131        for (i = 0; i < emu->max_voices; i++) {
     132                vp = &emu->voices[i];
     133                if (vp->state == SNDRV_EMUX_ST_STANDBY &&
     134                    vp->chan == chan) {
     135                        emu->ops.trigger(vp);
     136                        vp->state = SNDRV_EMUX_ST_ON;
     137                        vp->ontime = jiffies; /* remember the trigger timing */
     138                }
     139        }
     140        spin_unlock_irqrestore(&emu->voice_lock, flags);
    139141
    140142#ifdef SNDRV_EMUX_USE_RAW_EFFECT
    141     if (port->port_mode == SNDRV_EMUX_PORT_MODE_OSS_SYNTH) {
    142         /* clear voice position for the next note on this channel */
    143         snd_emux_effect_table_t *fx = chan->private;
    144         if (fx) {
    145             fx->flag[EMUX_FX_SAMPLE_START] = 0;
    146             fx->flag[EMUX_FX_COARSE_SAMPLE_START] = 0;
    147         }
    148     }
     143        if (port->port_mode == SNDRV_EMUX_PORT_MODE_OSS_SYNTH) {
     144                /* clear voice position for the next note on this channel */
     145                struct snd_emux_effect_table *fx = chan->private;
     146                if (fx) {
     147                        fx->flag[EMUX_FX_SAMPLE_START] = 0;
     148                        fx->flag[EMUX_FX_COARSE_SAMPLE_START] = 0;
     149                }
     150        }
    149151#endif
    150152}
     
    154156 */
    155157void
    156 snd_emux_note_off(void *p, int note, int vel, snd_midi_channel_t *chan)
    157 {
    158     int ch;
    159     snd_emux_t *emu;
    160     snd_emux_voice_t *vp;
    161     unsigned long flags;
    162     snd_emux_port_t *port;
    163 
    164     port = p;
    165     snd_assert(port != NULL && chan != NULL, return);
    166 
    167     emu = port->emu;
    168     snd_assert(emu != NULL, return);
    169     snd_assert(emu->ops.release != NULL, return);
    170 
    171     spin_lock_irqsave(&emu->voice_lock, flags);
    172     for (ch = 0; ch < emu->max_voices; ch++) {
    173         vp = &emu->voices[ch];
    174         if (STATE_IS_PLAYING(vp->state) &&
    175             vp->chan == chan && vp->key == note) {
    176             vp->time = emu->use_time++;
    177             vp->state = SNDRV_EMUX_ST_RELEASED;
    178             if (vp->ontime == jiffies) {
    179                 /* if note-off is sent too shortly after
    180                  * note-on, emuX engine cannot produce the sound
    181                  * correctly.  so we'll release this note
    182                  * a bit later via timer callback.
    183                  */
    184                 vp->state = SNDRV_EMUX_ST_PENDING;
    185                 if (! emu->timer_active) {
    186                     emu->tlist.expires = jiffies + 1;
    187                     add_timer(&emu->tlist);
    188                     emu->timer_active = 1;
    189                 }
    190             } else
    191                 /* ok now release the note */
    192                 emu->ops.release(vp);
    193         }
    194     }
    195     spin_unlock_irqrestore(&emu->voice_lock, flags);
     158snd_emux_note_off(void *p, int note, int vel, struct snd_midi_channel *chan)
     159{
     160        int ch;
     161        struct snd_emux *emu;
     162        struct snd_emux_voice *vp;
     163        unsigned long flags;
     164        struct snd_emux_port *port;
     165
     166        port = p;
     167        snd_assert(port != NULL && chan != NULL, return);
     168
     169        emu = port->emu;
     170        snd_assert(emu != NULL, return);
     171        snd_assert(emu->ops.release != NULL, return);
     172
     173        spin_lock_irqsave(&emu->voice_lock, flags);
     174        for (ch = 0; ch < emu->max_voices; ch++) {
     175                vp = &emu->voices[ch];
     176                if (STATE_IS_PLAYING(vp->state) &&
     177                    vp->chan == chan && vp->key == note) {
     178                        vp->state = SNDRV_EMUX_ST_RELEASED;
     179                        if (vp->ontime == jiffies) {
     180                                /* if note-off is sent too shortly after
     181                                 * note-on, emuX engine cannot produce the sound
     182                                 * correctly.  so we'll release this note
     183                                 * a bit later via timer callback.
     184                                 */
     185                                vp->state = SNDRV_EMUX_ST_PENDING;
     186                                if (! emu->timer_active) {
     187                                        emu->tlist.expires = jiffies + 1;
     188                                        add_timer(&emu->tlist);
     189                                        emu->timer_active = 1;
     190                                }
     191                        } else
     192                                /* ok now release the note */
     193                                emu->ops.release(vp);
     194                }
     195        }
     196        spin_unlock_irqrestore(&emu->voice_lock, flags);
    196197}
    197198
     
    203204void snd_emux_timer_callback(unsigned long data)
    204205{
    205     snd_emux_t *emu = (snd_emux_t*) data;
    206     snd_emux_voice_t *vp;
    207     int ch, do_again = 0;
    208 
    209     spin_lock(&emu->voice_lock);
    210     for (ch = 0; ch < emu->max_voices; ch++) {
    211         vp = &emu->voices[ch];
    212         if (vp->state == SNDRV_EMUX_ST_PENDING) {
    213             if (vp->ontime == jiffies)
    214                 do_again++; /* release this at the next interrupt */
    215             else {
    216                 emu->ops.release(vp);
    217                 vp->state = SNDRV_EMUX_ST_RELEASED;
    218             }
    219         }
    220     }
    221     if (do_again) {
    222         emu->tlist.expires = jiffies + 1;
    223         add_timer(&emu->tlist);
    224         emu->timer_active = 1;
    225     } else
    226         emu->timer_active = 0;
    227     spin_unlock(&emu->voice_lock);
     206        struct snd_emux *emu = (struct snd_emux *) data;
     207        struct snd_emux_voice *vp;
     208        int ch, do_again = 0;
     209
     210        spin_lock(&emu->voice_lock);
     211        for (ch = 0; ch < emu->max_voices; ch++) {
     212                vp = &emu->voices[ch];
     213                if (vp->state == SNDRV_EMUX_ST_PENDING) {
     214                        if (vp->ontime == jiffies)
     215                                do_again++; /* release this at the next interrupt */
     216                        else {
     217                                emu->ops.release(vp);
     218                                vp->state = SNDRV_EMUX_ST_RELEASED;
     219                        }
     220                }
     221        }
     222        if (do_again) {
     223                emu->tlist.expires = jiffies + 1;
     224                add_timer(&emu->tlist);
     225                emu->timer_active = 1;
     226        } else
     227                emu->timer_active = 0;
     228        spin_unlock(&emu->voice_lock);
    228229}
    229230
     
    232233 */
    233234void
    234 snd_emux_key_press(void *p, int note, int vel, snd_midi_channel_t *chan)
    235 {
    236     int ch;
    237     snd_emux_t *emu;
    238     snd_emux_voice_t *vp;
    239     unsigned long flags;
    240     snd_emux_port_t *port;
    241 
    242     port = p;
    243     snd_assert(port != NULL && chan != NULL, return);
    244 
    245     emu = port->emu;
    246     snd_assert(emu != NULL, return);
    247     snd_assert(emu->ops.update != NULL, return);
    248 
    249     spin_lock_irqsave(&emu->voice_lock, flags);
    250     for (ch = 0; ch < emu->max_voices; ch++) {
    251         vp = &emu->voices[ch];
    252         if (vp->state == SNDRV_EMUX_ST_ON &&
    253             vp->chan == chan && vp->key == note) {
    254             vp->velocity = vel;
    255             update_voice(emu, vp, SNDRV_EMUX_UPDATE_VOLUME);
    256         }
    257     }
    258     spin_unlock_irqrestore(&emu->voice_lock, flags);
     235snd_emux_key_press(void *p, int note, int vel, struct snd_midi_channel *chan)
     236{
     237        int ch;
     238        struct snd_emux *emu;
     239        struct snd_emux_voice *vp;
     240        unsigned long flags;
     241        struct snd_emux_port *port;
     242
     243        port = p;
     244        snd_assert(port != NULL && chan != NULL, return);
     245
     246        emu = port->emu;
     247        snd_assert(emu != NULL, return);
     248        snd_assert(emu->ops.update != NULL, return);
     249
     250        spin_lock_irqsave(&emu->voice_lock, flags);
     251        for (ch = 0; ch < emu->max_voices; ch++) {
     252                vp = &emu->voices[ch];
     253                if (vp->state == SNDRV_EMUX_ST_ON &&
     254                    vp->chan == chan && vp->key == note) {
     255                        vp->velocity = vel;
     256                        update_voice(emu, vp, SNDRV_EMUX_UPDATE_VOLUME);
     257                }
     258        }
     259        spin_unlock_irqrestore(&emu->voice_lock, flags);
    259260}
    260261
     
    264265 */
    265266void
    266 snd_emux_update_channel(snd_emux_port_t *port, snd_midi_channel_t *chan, int update)
    267 {
    268     snd_emux_t *emu;
    269     snd_emux_voice_t *vp;
    270     int i;
    271     unsigned long flags;
    272 
    273     if (! update)
    274         return;
    275 
    276     emu = port->emu;
    277     snd_assert(emu != NULL, return);
    278     snd_assert(emu->ops.update != NULL, return);
    279 
    280     spin_lock_irqsave(&emu->voice_lock, flags);
    281     for (i = 0; i < emu->max_voices; i++) {
    282         vp = &emu->voices[i];
    283         if (vp->chan == chan)
    284             update_voice(emu, vp, update);
    285     }
    286     spin_unlock_irqrestore(&emu->voice_lock, flags);
     267snd_emux_update_channel(struct snd_emux_port *port, struct snd_midi_channel *chan, int update)
     268{
     269        struct snd_emux *emu;
     270        struct snd_emux_voice *vp;
     271        int i;
     272        unsigned long flags;
     273
     274        if (! update)
     275                return;
     276
     277        emu = port->emu;
     278        snd_assert(emu != NULL, return);
     279        snd_assert(emu->ops.update != NULL, return);
     280
     281        spin_lock_irqsave(&emu->voice_lock, flags);
     282        for (i = 0; i < emu->max_voices; i++) {
     283                vp = &emu->voices[i];
     284                if (vp->chan == chan)
     285                        update_voice(emu, vp, update);
     286        }
     287        spin_unlock_irqrestore(&emu->voice_lock, flags);
    287288}
    288289
     
    291292 */
    292293void
    293 snd_emux_update_port(snd_emux_port_t *port, int update)
    294 {
    295     snd_emux_t *emu;
    296     snd_emux_voice_t *vp;
    297     int i;
    298     unsigned long flags;
    299 
    300     if (! update)
    301         return;
    302 
    303     emu = port->emu;
    304     snd_assert(emu != NULL, return);
    305     snd_assert(emu->ops.update != NULL, return);
    306 
    307     spin_lock_irqsave(&emu->voice_lock, flags);
    308     for (i = 0; i < emu->max_voices; i++) {
    309         vp = &emu->voices[i];
    310         if (vp->port == port)
    311             update_voice(emu, vp, update);
    312     }
    313     spin_unlock_irqrestore(&emu->voice_lock, flags);
     294snd_emux_update_port(struct snd_emux_port *port, int update)
     295{
     296        struct snd_emux *emu;
     297        struct snd_emux_voice *vp;
     298        int i;
     299        unsigned long flags;
     300
     301        if (! update)
     302                return;
     303
     304        emu = port->emu;
     305        snd_assert(emu != NULL, return);
     306        snd_assert(emu->ops.update != NULL, return);
     307
     308        spin_lock_irqsave(&emu->voice_lock, flags);
     309        for (i = 0; i < emu->max_voices; i++) {
     310                vp = &emu->voices[i];
     311                if (vp->port == port)
     312                        update_voice(emu, vp, update);
     313        }
     314        spin_unlock_irqrestore(&emu->voice_lock, flags);
    314315}
    315316
     
    320321 */
    321322void
    322 snd_emux_control(void *p, int type, snd_midi_channel_t *chan)
    323 {
    324     snd_emux_port_t *port;
    325 
    326     port = p;
    327     snd_assert(port != NULL && chan != NULL, return);
    328 
    329     switch (type) {
    330     case MIDI_CTL_MSB_MAIN_VOLUME:
    331     case MIDI_CTL_MSB_EXPRESSION:
    332         snd_emux_update_channel(port, chan, SNDRV_EMUX_UPDATE_VOLUME);
    333         break;
    334 
    335     case MIDI_CTL_MSB_PAN:
    336         snd_emux_update_channel(port, chan, SNDRV_EMUX_UPDATE_PAN);
    337         break;
    338 
    339     case MIDI_CTL_SOFT_PEDAL:
     323snd_emux_control(void *p, int type, struct snd_midi_channel *chan)
     324{
     325        struct snd_emux_port *port;
     326
     327        port = p;
     328        snd_assert(port != NULL && chan != NULL, return);
     329
     330        switch (type) {
     331        case MIDI_CTL_MSB_MAIN_VOLUME:
     332        case MIDI_CTL_MSB_EXPRESSION:
     333                snd_emux_update_channel(port, chan, SNDRV_EMUX_UPDATE_VOLUME);
     334                break;
     335               
     336        case MIDI_CTL_MSB_PAN:
     337                snd_emux_update_channel(port, chan, SNDRV_EMUX_UPDATE_PAN);
     338                break;
     339
     340        case MIDI_CTL_SOFT_PEDAL:
    340341#ifdef SNDRV_EMUX_USE_RAW_EFFECT
    341         /* FIXME: this is an emulation */
    342         snd_emux_send_effect(port, chan, EMUX_FX_CUTOFF, -160,
    343                              EMUX_FX_FLAG_ADD);
     342                /* FIXME: this is an emulation */
     343                snd_emux_send_effect(port, chan, EMUX_FX_CUTOFF, -160,
     344                                     EMUX_FX_FLAG_ADD);
    344345#endif
    345         break;
    346 
    347     case MIDI_CTL_PITCHBEND:
    348         snd_emux_update_channel(port, chan, SNDRV_EMUX_UPDATE_PITCH);
    349         break;
    350 
    351     case MIDI_CTL_MSB_MODWHEEL:
    352     case MIDI_CTL_CHAN_PRESSURE:
    353         snd_emux_update_channel(port, chan,
    354                                 SNDRV_EMUX_UPDATE_FMMOD |
    355                                 SNDRV_EMUX_UPDATE_FM2FRQ2);
    356         break;
    357 
    358     }
    359 
    360     if (port->chset.midi_mode == SNDRV_MIDI_MODE_XG) {
    361         snd_emux_xg_control(port, chan, type);
    362     }
    363 }
    364 
    365 
    366 /*
    367  * for Emu10k1 - release at least 1 voice currently using
    368  */
    369 int
    370 snd_emux_release_voice(snd_emux_t *emu)
    371 {
    372     return 0;
     346                break;
     347
     348        case MIDI_CTL_PITCHBEND:
     349                snd_emux_update_channel(port, chan, SNDRV_EMUX_UPDATE_PITCH);
     350                break;
     351
     352        case MIDI_CTL_MSB_MODWHEEL:
     353        case MIDI_CTL_CHAN_PRESSURE:
     354                snd_emux_update_channel(port, chan,
     355                                        SNDRV_EMUX_UPDATE_FMMOD |
     356                                        SNDRV_EMUX_UPDATE_FM2FRQ2);
     357                break;
     358
     359        }
     360
     361        if (port->chset.midi_mode == SNDRV_MIDI_MODE_XG) {
     362                snd_emux_xg_control(port, chan, type);
     363        }
    373364}
    374365
     
    378369 */
    379370static void
    380 terminate_note1(snd_emux_t *emu, int note, snd_midi_channel_t *chan, int free)
    381 {
    382     int  i;
    383     snd_emux_voice_t *vp;
    384     unsigned long flags;
    385 
    386     spin_lock_irqsave(&emu->voice_lock, flags);
    387     for (i = 0; i < emu->max_voices; i++) {
    388         vp = &emu->voices[i];
    389         if (STATE_IS_PLAYING(vp->state) && vp->chan == chan &&
    390             vp->key == note)
    391             terminate_voice(emu, vp, free);
    392     }
    393     spin_unlock_irqrestore(&emu->voice_lock, flags);
     371terminate_note1(struct snd_emux *emu, int note, struct snd_midi_channel *chan, int free)
     372{
     373        int  i;
     374        struct snd_emux_voice *vp;
     375        unsigned long flags;
     376
     377        spin_lock_irqsave(&emu->voice_lock, flags);
     378        for (i = 0; i < emu->max_voices; i++) {
     379                vp = &emu->voices[i];
     380                if (STATE_IS_PLAYING(vp->state) && vp->chan == chan &&
     381                    vp->key == note)
     382                        terminate_voice(emu, vp, free);
     383        }
     384        spin_unlock_irqrestore(&emu->voice_lock, flags);
    394385}
    395386
     
    399390 */
    400391void
    401 snd_emux_terminate_note(void *p, int note, snd_midi_channel_t *chan)
    402 {
    403     snd_emux_t *emu;
    404     snd_emux_port_t *port;
    405 
    406     port = p;
    407     snd_assert(port != NULL && chan != NULL, return);
    408 
    409     emu = port->emu;
    410     snd_assert(emu != NULL, return);
    411     snd_assert(emu->ops.terminate != NULL, return);
    412 
    413     terminate_note1(emu, note, chan, 1);
     392snd_emux_terminate_note(void *p, int note, struct snd_midi_channel *chan)
     393{
     394        struct snd_emux *emu;
     395        struct snd_emux_port *port;
     396
     397        port = p;
     398        snd_assert(port != NULL && chan != NULL, return);
     399
     400        emu = port->emu;
     401        snd_assert(emu != NULL, return);
     402        snd_assert(emu->ops.terminate != NULL, return);
     403
     404        terminate_note1(emu, note, chan, 1);
    414405}
    415406
     
    419410 */
    420411void
    421 snd_emux_terminate_all(snd_emux_t *emu)
    422 {
    423     int i;
    424     snd_emux_voice_t *vp;
    425     unsigned long flags;
    426 
    427     spin_lock_irqsave(&emu->voice_lock, flags);
    428     for (i = 0; i < emu->max_voices; i++) {
    429         vp = &emu->voices[i];
    430         if (STATE_IS_PLAYING(vp->state))
    431             terminate_voice(emu, vp, 0);
    432         if (vp->state == SNDRV_EMUX_ST_OFF) {
    433             if (emu->ops.free_voice)
    434                 emu->ops.free_voice(vp);
    435             if (emu->ops.reset)
    436                 emu->ops.reset(emu, i);
    437         }
    438         vp->time = 0;
    439     }
    440     /* initialize allocation time */
    441     emu->use_time = 0;
    442     spin_unlock_irqrestore(&emu->voice_lock, flags);
     412snd_emux_terminate_all(struct snd_emux *emu)
     413{
     414        int i;
     415        struct snd_emux_voice *vp;
     416        unsigned long flags;
     417
     418        spin_lock_irqsave(&emu->voice_lock, flags);
     419        for (i = 0; i < emu->max_voices; i++) {
     420                vp = &emu->voices[i];
     421                if (STATE_IS_PLAYING(vp->state))
     422                        terminate_voice(emu, vp, 0);
     423                if (vp->state == SNDRV_EMUX_ST_OFF) {
     424                        if (emu->ops.free_voice)
     425                                emu->ops.free_voice(vp);
     426                        if (emu->ops.reset)
     427                                emu->ops.reset(emu, i);
     428                }
     429                vp->time = 0;
     430        }
     431        /* initialize allocation time */
     432        emu->use_time = 0;
     433        spin_unlock_irqrestore(&emu->voice_lock, flags);
    443434}
    444435
     
    448439 */
    449440void
    450 snd_emux_sounds_off_all(snd_emux_port_t *port)
    451 {
    452     int i;
    453     snd_emux_t *emu;
    454     snd_emux_voice_t *vp;
    455     unsigned long flags;
    456 
    457     snd_assert(port != NULL, return);
    458     emu = port->emu;
    459     snd_assert(emu != NULL, return);
    460     snd_assert(emu->ops.terminate != NULL, return);
    461 
    462     spin_lock_irqsave(&emu->voice_lock, flags);
    463     for (i = 0; i < emu->max_voices; i++) {
    464         vp = &emu->voices[i];
    465         if (STATE_IS_PLAYING(vp->state) &&
    466             vp->port == port)
    467             terminate_voice(emu, vp, 0);
    468         if (vp->state == SNDRV_EMUX_ST_OFF) {
    469             if (emu->ops.free_voice)
    470                 emu->ops.free_voice(vp);
    471             if (emu->ops.reset)
    472                 emu->ops.reset(emu, i);
    473         }
    474     }
    475     spin_unlock_irqrestore(&emu->voice_lock, flags);
     441snd_emux_sounds_off_all(struct snd_emux_port *port)
     442{
     443        int i;
     444        struct snd_emux *emu;
     445        struct snd_emux_voice *vp;
     446        unsigned long flags;
     447
     448        snd_assert(port != NULL, return);
     449        emu = port->emu;
     450        snd_assert(emu != NULL, return);
     451        snd_assert(emu->ops.terminate != NULL, return);
     452
     453        spin_lock_irqsave(&emu->voice_lock, flags);
     454        for (i = 0; i < emu->max_voices; i++) {
     455                vp = &emu->voices[i];
     456                if (STATE_IS_PLAYING(vp->state) &&
     457                    vp->port == port)
     458                        terminate_voice(emu, vp, 0);
     459                if (vp->state == SNDRV_EMUX_ST_OFF) {
     460                        if (emu->ops.free_voice)
     461                                emu->ops.free_voice(vp);
     462                        if (emu->ops.reset)
     463                                emu->ops.reset(emu, i);
     464                }
     465        }
     466        spin_unlock_irqrestore(&emu->voice_lock, flags);
    476467}
    477468
     
    482473 */
    483474static void
    484 exclusive_note_off(snd_emux_t *emu, snd_emux_port_t *port, int exclass)
    485 {
    486     snd_emux_voice_t *vp;
    487     int  i;
    488     unsigned long flags;
    489 
    490     spin_lock_irqsave(&emu->voice_lock, flags);
    491     for (i = 0; i < emu->max_voices; i++) {
    492         vp = &emu->voices[i];
    493         if (STATE_IS_PLAYING(vp->state) && vp->port == port &&
    494             vp->reg.exclusiveClass == exclass) {
    495             terminate_voice(emu, vp, 0);
    496         }
    497     }
    498     spin_unlock_irqrestore(&emu->voice_lock, flags);
     475exclusive_note_off(struct snd_emux *emu, struct snd_emux_port *port, int exclass)
     476{
     477        struct snd_emux_voice *vp;
     478        int  i;
     479        unsigned long flags;
     480
     481        spin_lock_irqsave(&emu->voice_lock, flags);
     482        for (i = 0; i < emu->max_voices; i++) {
     483                vp = &emu->voices[i];
     484                if (STATE_IS_PLAYING(vp->state) && vp->port == port &&
     485                    vp->reg.exclusiveClass == exclass) {
     486                        terminate_voice(emu, vp, 0);
     487                }
     488        }
     489        spin_unlock_irqrestore(&emu->voice_lock, flags);
    499490}
    500491
     
    504495 */
    505496static void
    506 terminate_voice(snd_emux_t *emu, snd_emux_voice_t *vp, int free)
    507 {
    508     emu->ops.terminate(vp);
    509     vp->time = emu->use_time++;
    510     vp->chan = NULL;
    511     vp->port = NULL;
    512     vp->zone = NULL;
    513     vp->block = NULL;
    514     vp->state = SNDRV_EMUX_ST_OFF;
    515     if (free && emu->ops.free_voice)
    516         emu->ops.free_voice(vp);
     497terminate_voice(struct snd_emux *emu, struct snd_emux_voice *vp, int free)
     498{
     499        emu->ops.terminate(vp);
     500        vp->time = emu->use_time++;
     501        vp->chan = NULL;
     502        vp->port = NULL;
     503        vp->zone = NULL;
     504        vp->block = NULL;
     505        vp->state = SNDRV_EMUX_ST_OFF;
     506        if (free && emu->ops.free_voice)
     507                emu->ops.free_voice(vp);
    517508}
    518509
     
    522513 */
    523514static void
    524 update_voice(snd_emux_t *emu, snd_emux_voice_t *vp, int update)
    525 {
    526     if (!STATE_IS_PLAYING(vp->state))
    527         return;
    528 
    529     if (vp->chan == NULL || vp->port == NULL)
    530         return;
    531     if (update & SNDRV_EMUX_UPDATE_VOLUME)
    532         calc_volume(vp);
    533     if (update & SNDRV_EMUX_UPDATE_PITCH)
    534         calc_pitch(vp);
    535     if (update & SNDRV_EMUX_UPDATE_PAN) {
    536         if (! calc_pan(vp) && (update == SNDRV_EMUX_UPDATE_PAN))
    537             return;
    538     }
    539     emu->ops.update(vp, update);
     515update_voice(struct snd_emux *emu, struct snd_emux_voice *vp, int update)
     516{
     517        if (!STATE_IS_PLAYING(vp->state))
     518                return;
     519
     520        if (vp->chan == NULL || vp->port == NULL)
     521                return;
     522        if (update & SNDRV_EMUX_UPDATE_VOLUME)
     523                calc_volume(vp);
     524        if (update & SNDRV_EMUX_UPDATE_PITCH)
     525                calc_pitch(vp);
     526        if (update & SNDRV_EMUX_UPDATE_PAN) {
     527                if (! calc_pan(vp) && (update == SNDRV_EMUX_UPDATE_PAN))
     528                        return;
     529        }
     530        emu->ops.update(vp, update);
    540531}
    541532
     
    543534#if 0 // not used
    544535/* table for volume target calculation */
    545 static unsigned short voltarget[16] = {
    546     0xEAC0, 0xE0C8, 0xD740, 0xCE20, 0xC560, 0xBD08, 0xB500, 0xAD58,
    547     0xA5F8, 0x9EF0, 0x9830, 0x91C0, 0x8B90, 0x85A8, 0x8000, 0x7A90
     536static unsigned short voltarget[16] = { 
     537        0xEAC0, 0xE0C8, 0xD740, 0xCE20, 0xC560, 0xBD08, 0xB500, 0xAD58,
     538        0xA5F8, 0x9EF0, 0x9830, 0x91C0, 0x8B90, 0x85A8, 0x8000, 0x7A90
    548539};
    549540#endif
     
    557548 */
    558549static void
    559 setup_voice(snd_emux_voice_t *vp)
    560 {
    561     soundfont_voice_parm_t *parm;
    562     int pitch;
    563 
    564     /* copy the original register values */
    565     vp->reg = vp->zone->v;
     550setup_voice(struct snd_emux_voice *vp)
     551{
     552        struct soundfont_voice_parm *parm;
     553        int pitch;
     554
     555        /* copy the original register values */
     556        vp->reg = vp->zone->v;
    566557
    567558#ifdef SNDRV_EMUX_USE_RAW_EFFECT
    568     snd_emux_setup_effect(vp);
     559        snd_emux_setup_effect(vp);
    569560#endif
    570561
    571     /* reset status */
    572     vp->apan = -1;
    573     vp->avol = -1;
    574     vp->apitch = -1;
    575 
    576     calc_volume(vp);
    577     calc_pitch(vp);
    578     calc_pan(vp);
    579 
    580     parm = &vp->reg.parm;
    581 
    582     /* compute filter target and correct modulation parameters */
    583     if (LO_BYTE(parm->modatkhld) >= 0x80 && parm->moddelay >= 0x8000) {
    584         parm->moddelay = 0xbfff;
    585         pitch = (HI_BYTE(parm->pefe) << 4) + vp->apitch;
    586         if (pitch > 0xffff)
    587             pitch = 0xffff;
    588         /* calculate filter target */
    589         vp->ftarget = parm->cutoff + LO_BYTE(parm->pefe);
    590         LIMITVALUE(vp->ftarget, 0, 255);
    591         vp->ftarget <<= 8;
    592     } else {
    593         vp->ftarget = parm->cutoff;
    594         vp->ftarget <<= 8;
    595         pitch = vp->apitch;
    596     }
    597 
    598     /* compute pitch target */
    599     if (pitch != 0xffff) {
    600         vp->ptarget = 1 << (pitch >> 12);
    601         if (pitch & 0x800) vp->ptarget += (vp->ptarget*0x102e)/0x2710;
    602         if (pitch & 0x400) vp->ptarget += (vp->ptarget*0x764)/0x2710;
    603         if (pitch & 0x200) vp->ptarget += (vp->ptarget*0x389)/0x2710;
    604         vp->ptarget += (vp->ptarget >> 1);
    605         if (vp->ptarget > 0xffff) vp->ptarget = 0xffff;
    606     } else
    607         vp->ptarget = 0xffff;
    608 
    609     if (LO_BYTE(parm->modatkhld) >= 0x80) {
    610         parm->modatkhld &= ~0xff;
    611         parm->modatkhld |= 0x7f;
    612     }
    613 
    614     /* compute volume target and correct volume parameters */
    615     vp->vtarget = 0;
     562        /* reset status */
     563        vp->apan = -1;
     564        vp->avol = -1;
     565        vp->apitch = -1;
     566
     567        calc_volume(vp);
     568        calc_pitch(vp);
     569        calc_pan(vp);
     570
     571        parm = &vp->reg.parm;
     572
     573        /* compute filter target and correct modulation parameters */
     574        if (LO_BYTE(parm->modatkhld) >= 0x80 && parm->moddelay >= 0x8000) {
     575                parm->moddelay = 0xbfff;
     576                pitch = (HI_BYTE(parm->pefe) << 4) + vp->apitch;
     577                if (pitch > 0xffff)
     578                        pitch = 0xffff;
     579                /* calculate filter target */
     580                vp->ftarget = parm->cutoff + LO_BYTE(parm->pefe);
     581                LIMITVALUE(vp->ftarget, 0, 255);
     582                vp->ftarget <<= 8;
     583        } else {
     584                vp->ftarget = parm->cutoff;
     585                vp->ftarget <<= 8;
     586                pitch = vp->apitch;
     587        }
     588
     589        /* compute pitch target */
     590        if (pitch != 0xffff) {
     591                vp->ptarget = 1 << (pitch >> 12);
     592                if (pitch & 0x800) vp->ptarget += (vp->ptarget*0x102e)/0x2710;
     593                if (pitch & 0x400) vp->ptarget += (vp->ptarget*0x764)/0x2710;
     594                if (pitch & 0x200) vp->ptarget += (vp->ptarget*0x389)/0x2710;
     595                vp->ptarget += (vp->ptarget >> 1);
     596                if (vp->ptarget > 0xffff) vp->ptarget = 0xffff;
     597        } else
     598                vp->ptarget = 0xffff;
     599
     600        if (LO_BYTE(parm->modatkhld) >= 0x80) {
     601                parm->modatkhld &= ~0xff;
     602                parm->modatkhld |= 0x7f;
     603        }
     604
     605        /* compute volume target and correct volume parameters */
     606        vp->vtarget = 0;
    616607#if 0 /* FIXME: this leads to some clicks.. */
    617     if (LO_BYTE(parm->volatkhld) >= 0x80 && parm->voldelay >= 0x8000) {
    618         parm->voldelay = 0xbfff;
    619         vp->vtarget = voltarget[vp->avol % 0x10] >> (vp->avol >> 4);
    620     }
     608        if (LO_BYTE(parm->volatkhld) >= 0x80 && parm->voldelay >= 0x8000) {
     609                parm->voldelay = 0xbfff;
     610                vp->vtarget = voltarget[vp->avol % 0x10] >> (vp->avol >> 4);
     611        }
    621612#endif
    622613
    623     if (LO_BYTE(parm->volatkhld) >= 0x80) {
    624         parm->volatkhld &= ~0xff;
    625         parm->volatkhld |= 0x7f;
    626     }
     614        if (LO_BYTE(parm->volatkhld) >= 0x80) {
     615                parm->volatkhld &= ~0xff;
     616                parm->volatkhld |= 0x7f;
     617        }
    627618}
    628619
     
    631622 */
    632623static unsigned char pan_volumes[256] = {
    633     0x00,0x03,0x06,0x09,0x0c,0x0f,0x12,0x14,0x17,0x1a,0x1d,0x20,0x22,0x25,0x28,0x2a,
    634     0x2d,0x30,0x32,0x35,0x37,0x3a,0x3c,0x3f,0x41,0x44,0x46,0x49,0x4b,0x4d,0x50,0x52,
    635     0x54,0x57,0x59,0x5b,0x5d,0x60,0x62,0x64,0x66,0x68,0x6a,0x6c,0x6f,0x71,0x73,0x75,
    636     0x77,0x79,0x7b,0x7c,0x7e,0x80,0x82,0x84,0x86,0x88,0x89,0x8b,0x8d,0x8f,0x90,0x92,
    637     0x94,0x96,0x97,0x99,0x9a,0x9c,0x9e,0x9f,0xa1,0xa2,0xa4,0xa5,0xa7,0xa8,0xaa,0xab,
    638     0xad,0xae,0xaf,0xb1,0xb2,0xb3,0xb5,0xb6,0xb7,0xb9,0xba,0xbb,0xbc,0xbe,0xbf,0xc0,
    639     0xc1,0xc2,0xc3,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xcb,0xcc,0xcd,0xce,0xcf,0xd0,0xd1,
    640     0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd7,0xd8,0xd9,0xda,0xdb,0xdc,0xdc,0xdd,0xde,0xdf,
    641     0xdf,0xe0,0xe1,0xe2,0xe2,0xe3,0xe4,0xe4,0xe5,0xe6,0xe6,0xe7,0xe8,0xe8,0xe9,0xe9,
    642     0xea,0xeb,0xeb,0xec,0xec,0xed,0xed,0xee,0xee,0xef,0xef,0xf0,0xf0,0xf1,0xf1,0xf1,
    643     0xf2,0xf2,0xf3,0xf3,0xf3,0xf4,0xf4,0xf5,0xf5,0xf5,0xf6,0xf6,0xf6,0xf7,0xf7,0xf7,
    644     0xf7,0xf8,0xf8,0xf8,0xf9,0xf9,0xf9,0xf9,0xf9,0xfa,0xfa,0xfa,0xfa,0xfb,0xfb,0xfb,
    645     0xfb,0xfb,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,
    646     0xfd,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,
    647     0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
    648     0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
     6240x00,0x03,0x06,0x09,0x0c,0x0f,0x12,0x14,0x17,0x1a,0x1d,0x20,0x22,0x25,0x28,0x2a,
     6250x2d,0x30,0x32,0x35,0x37,0x3a,0x3c,0x3f,0x41,0x44,0x46,0x49,0x4b,0x4d,0x50,0x52,
     6260x54,0x57,0x59,0x5b,0x5d,0x60,0x62,0x64,0x66,0x68,0x6a,0x6c,0x6f,0x71,0x73,0x75,
     6270x77,0x79,0x7b,0x7c,0x7e,0x80,0x82,0x84,0x86,0x88,0x89,0x8b,0x8d,0x8f,0x90,0x92,
     6280x94,0x96,0x97,0x99,0x9a,0x9c,0x9e,0x9f,0xa1,0xa2,0xa4,0xa5,0xa7,0xa8,0xaa,0xab,
     6290xad,0xae,0xaf,0xb1,0xb2,0xb3,0xb5,0xb6,0xb7,0xb9,0xba,0xbb,0xbc,0xbe,0xbf,0xc0,
     6300xc1,0xc2,0xc3,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xcb,0xcc,0xcd,0xce,0xcf,0xd0,0xd1,
     6310xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd7,0xd8,0xd9,0xda,0xdb,0xdc,0xdc,0xdd,0xde,0xdf,
     6320xdf,0xe0,0xe1,0xe2,0xe2,0xe3,0xe4,0xe4,0xe5,0xe6,0xe6,0xe7,0xe8,0xe8,0xe9,0xe9,
     6330xea,0xeb,0xeb,0xec,0xec,0xed,0xed,0xee,0xee,0xef,0xef,0xf0,0xf0,0xf1,0xf1,0xf1,
     6340xf2,0xf2,0xf3,0xf3,0xf3,0xf4,0xf4,0xf5,0xf5,0xf5,0xf6,0xf6,0xf6,0xf7,0xf7,0xf7,
     6350xf7,0xf8,0xf8,0xf8,0xf9,0xf9,0xf9,0xf9,0xf9,0xfa,0xfa,0xfa,0xfa,0xfb,0xfb,0xfb,
     6360xfb,0xfb,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,
     6370xfd,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,
     6380xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
     6390xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
    649640};
    650641
    651642static int
    652 calc_pan(snd_emux_voice_t *vp)
    653 {
    654     snd_midi_channel_t *chan = vp->chan;
    655     int pan;
    656 
    657     /* pan & loop start (pan 8bit, MSB, 0:right, 0xff:left) */
    658     if (vp->reg.fixpan > 0)     /* 0-127 */
    659         pan = 255 - (int)vp->reg.fixpan * 2;
    660     else {
    661         pan = chan->control[MIDI_CTL_MSB_PAN] - 64;
    662         if (vp->reg.pan >= 0) /* 0-127 */
    663             pan += vp->reg.pan - 64;
    664         pan = 127 - (int)pan * 2;
    665     }
    666     LIMITVALUE(pan, 0, 255);
    667 
    668 #if 1
    669     /* using volume table */
    670     if (vp->apan != (int)pan_volumes[pan]) {
    671         vp->apan = pan_volumes[pan];
    672         vp->aaux = pan_volumes[255 - pan];
    673         return 1;
    674     }
    675     return 0;
    676 #else
    677     /* assuming linear volume */
    678     if (pan != vp->apan) {
    679         vp->apan = pan;
    680         if (pan == 0)
    681             vp->aaux = 0xff;
    682         else
    683             vp->aaux = (-pan) & 0xff;
    684         return 1;
    685     } else
    686         return 0;
    687 #endif
     643calc_pan(struct snd_emux_voice *vp)
     644{
     645        struct snd_midi_channel *chan = vp->chan;
     646        int pan;
     647
     648        /* pan & loop start (pan 8bit, MSB, 0:right, 0xff:left) */
     649        if (vp->reg.fixpan > 0) /* 0-127 */
     650                pan = 255 - (int)vp->reg.fixpan * 2;
     651        else {
     652                pan = chan->control[MIDI_CTL_MSB_PAN] - 64;
     653                if (vp->reg.pan >= 0) /* 0-127 */
     654                        pan += vp->reg.pan - 64;
     655                pan = 127 - (int)pan * 2;
     656        }
     657        LIMITVALUE(pan, 0, 255);
     658
     659        if (vp->emu->linear_panning) {
     660                /* assuming linear volume */
     661                if (pan != vp->apan) {
     662                        vp->apan = pan;
     663                        if (pan == 0)
     664                                vp->aaux = 0xff;
     665                        else
     666                                vp->aaux = (-pan) & 0xff;
     667                        return 1;
     668                } else
     669                        return 0;
     670        } else {
     671                /* using volume table */
     672                if (vp->apan != (int)pan_volumes[pan]) {
     673                        vp->apan = pan_volumes[pan];
     674                        vp->aaux = pan_volumes[255 - pan];
     675                        return 1;
     676                }
     677                return 0;
     678        }
    688679}
    689680
     
    699690/* tables for volume->attenuation calculation */
    700691static unsigned char voltab1[128] = {
    701     0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
    702     0x63, 0x2b, 0x29, 0x28, 0x27, 0x26, 0x25, 0x24, 0x23, 0x22,
    703     0x21, 0x20, 0x1f, 0x1e, 0x1e, 0x1d, 0x1c, 0x1b, 0x1b, 0x1a,
    704     0x19, 0x19, 0x18, 0x17, 0x17, 0x16, 0x16, 0x15, 0x15, 0x14,
    705     0x14, 0x13, 0x13, 0x13, 0x12, 0x12, 0x11, 0x11, 0x11, 0x10,
    706     0x10, 0x10, 0x0f, 0x0f, 0x0f, 0x0e, 0x0e, 0x0e, 0x0e, 0x0d,
    707     0x0d, 0x0d, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0b, 0x0b, 0x0b,
    708     0x0b, 0x0a, 0x0a, 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09,
    709     0x08, 0x08, 0x08, 0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x06,
    710     0x06, 0x06, 0x06, 0x06, 0x05, 0x05, 0x05, 0x05, 0x05, 0x04,
    711     0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02,
    712     0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01,
    713     0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
     692   0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
     693   0x63, 0x2b, 0x29, 0x28, 0x27, 0x26, 0x25, 0x24, 0x23, 0x22,
     694   0x21, 0x20, 0x1f, 0x1e, 0x1e, 0x1d, 0x1c, 0x1b, 0x1b, 0x1a,
     695   0x19, 0x19, 0x18, 0x17, 0x17, 0x16, 0x16, 0x15, 0x15, 0x14,
     696   0x14, 0x13, 0x13, 0x13, 0x12, 0x12, 0x11, 0x11, 0x11, 0x10,
     697   0x10, 0x10, 0x0f, 0x0f, 0x0f, 0x0e, 0x0e, 0x0e, 0x0e, 0x0d,
     698   0x0d, 0x0d, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0b, 0x0b, 0x0b,
     699   0x0b, 0x0a, 0x0a, 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09,
     700   0x08, 0x08, 0x08, 0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x06,
     701   0x06, 0x06, 0x06, 0x06, 0x05, 0x05, 0x05, 0x05, 0x05, 0x04,
     702   0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02,
     703   0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01,
     704   0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
    714705};
    715706
    716707static unsigned char voltab2[128] = {
    717     0x32, 0x31, 0x30, 0x2f, 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x2a,
    718     0x29, 0x28, 0x27, 0x26, 0x25, 0x24, 0x24, 0x23, 0x22, 0x21,
    719     0x21, 0x20, 0x1f, 0x1e, 0x1e, 0x1d, 0x1c, 0x1c, 0x1b, 0x1a,
    720     0x1a, 0x19, 0x19, 0x18, 0x18, 0x17, 0x16, 0x16, 0x15, 0x15,
    721     0x14, 0x14, 0x13, 0x13, 0x13, 0x12, 0x12, 0x11, 0x11, 0x10,
    722     0x10, 0x10, 0x0f, 0x0f, 0x0f, 0x0e, 0x0e, 0x0e, 0x0d, 0x0d,
    723     0x0d, 0x0c, 0x0c, 0x0c, 0x0b, 0x0b, 0x0b, 0x0b, 0x0a, 0x0a,
    724     0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x08, 0x08, 0x08,
    725     0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x07, 0x06, 0x06, 0x06,
    726     0x06, 0x06, 0x06, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
    727     0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03,
    728     0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01,
    729     0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00
     708   0x32, 0x31, 0x30, 0x2f, 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x2a,
     709   0x29, 0x28, 0x27, 0x26, 0x25, 0x24, 0x24, 0x23, 0x22, 0x21,
     710   0x21, 0x20, 0x1f, 0x1e, 0x1e, 0x1d, 0x1c, 0x1c, 0x1b, 0x1a,
     711   0x1a, 0x19, 0x19, 0x18, 0x18, 0x17, 0x16, 0x16, 0x15, 0x15,
     712   0x14, 0x14, 0x13, 0x13, 0x13, 0x12, 0x12, 0x11, 0x11, 0x10,
     713   0x10, 0x10, 0x0f, 0x0f, 0x0f, 0x0e, 0x0e, 0x0e, 0x0d, 0x0d,
     714   0x0d, 0x0c, 0x0c, 0x0c, 0x0b, 0x0b, 0x0b, 0x0b, 0x0a, 0x0a,
     715   0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x08, 0x08, 0x08,
     716   0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x07, 0x06, 0x06, 0x06,
     717   0x06, 0x06, 0x06, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
     718   0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03,
     719   0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01,
     720   0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00
    730721};
    731722
    732723static unsigned char expressiontab[128] = {
    733     0x7f, 0x6c, 0x62, 0x5a, 0x54, 0x50, 0x4b, 0x48, 0x45, 0x42,
    734     0x40, 0x3d, 0x3b, 0x39, 0x38, 0x36, 0x34, 0x33, 0x31, 0x30,
    735     0x2f, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, 0x27, 0x26, 0x25,
    736     0x24, 0x24, 0x23, 0x22, 0x21, 0x21, 0x20, 0x1f, 0x1e, 0x1e,
    737     0x1d, 0x1d, 0x1c, 0x1b, 0x1b, 0x1a, 0x1a, 0x19, 0x18, 0x18,
    738     0x17, 0x17, 0x16, 0x16, 0x15, 0x15, 0x15, 0x14, 0x14, 0x13,
    739     0x13, 0x12, 0x12, 0x11, 0x11, 0x11, 0x10, 0x10, 0x0f, 0x0f,
    740     0x0f, 0x0e, 0x0e, 0x0e, 0x0d, 0x0d, 0x0d, 0x0c, 0x0c, 0x0c,
    741     0x0b, 0x0b, 0x0b, 0x0a, 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09,
    742     0x08, 0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x06, 0x06, 0x06,
    743     0x06, 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03,
    744     0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01,
    745     0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
     724   0x7f, 0x6c, 0x62, 0x5a, 0x54, 0x50, 0x4b, 0x48, 0x45, 0x42,
     725   0x40, 0x3d, 0x3b, 0x39, 0x38, 0x36, 0x34, 0x33, 0x31, 0x30,
     726   0x2f, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, 0x27, 0x26, 0x25,
     727   0x24, 0x24, 0x23, 0x22, 0x21, 0x21, 0x20, 0x1f, 0x1e, 0x1e,
     728   0x1d, 0x1d, 0x1c, 0x1b, 0x1b, 0x1a, 0x1a, 0x19, 0x18, 0x18,
     729   0x17, 0x17, 0x16, 0x16, 0x15, 0x15, 0x15, 0x14, 0x14, 0x13,
     730   0x13, 0x12, 0x12, 0x11, 0x11, 0x11, 0x10, 0x10, 0x0f, 0x0f,
     731   0x0f, 0x0e, 0x0e, 0x0e, 0x0d, 0x0d, 0x0d, 0x0c, 0x0c, 0x0c,
     732   0x0b, 0x0b, 0x0b, 0x0a, 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09,
     733   0x08, 0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x06, 0x06, 0x06,
     734   0x06, 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03,
     735   0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01,
     736   0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
    746737};
    747738
     
    751742 */
    752743static int
    753 calc_volume(snd_emux_voice_t *vp)
    754 {
    755     int vol;
    756     int main_vol, expression_vol, master_vol;
    757     snd_midi_channel_t *chan = vp->chan;
    758     snd_emux_port_t *port = vp->port;
    759 
    760     expression_vol = chan->control[MIDI_CTL_MSB_EXPRESSION];
    761     LIMITMAX(vp->velocity, 127);
    762     LIMITVALUE(expression_vol, 0, 127);
    763     if (port->port_mode == SNDRV_EMUX_PORT_MODE_OSS_SYNTH) {
    764         /* 0 - 127 */
    765         main_vol = chan->control[MIDI_CTL_MSB_MAIN_VOLUME];
    766         vol = (vp->velocity * main_vol * expression_vol) / (127*127);
    767         vol = vol * vp->reg.amplitude / 127;
    768 
    769         LIMITVALUE(vol, 0, 127);
    770 
    771         /* calc to attenuation */
    772         vol = snd_sf_vol_table[vol];
    773 
    774     } else {
    775         main_vol = chan->control[MIDI_CTL_MSB_MAIN_VOLUME] * vp->reg.amplitude / 127;
    776         LIMITVALUE(main_vol, 0, 127);
    777 
    778         vol = voltab1[main_vol] + voltab2[vp->velocity];
    779         vol = (vol * 8) / 3;
    780         vol += vp->reg.attenuation;
    781         vol += ((0x100 - vol) * expressiontab[expression_vol])/128;
    782     }
    783 
    784     master_vol = port->chset.gs_master_volume;
    785     LIMITVALUE(master_vol, 0, 127);
    786     vol += snd_sf_vol_table[master_vol];
    787     vol += port->volume_atten;
     744calc_volume(struct snd_emux_voice *vp)
     745{
     746        int vol;
     747        int main_vol, expression_vol, master_vol;
     748        struct snd_midi_channel *chan = vp->chan;
     749        struct snd_emux_port *port = vp->port;
     750
     751        expression_vol = chan->control[MIDI_CTL_MSB_EXPRESSION];
     752        LIMITMAX(vp->velocity, 127);
     753        LIMITVALUE(expression_vol, 0, 127);
     754        if (port->port_mode == SNDRV_EMUX_PORT_MODE_OSS_SYNTH) {
     755                /* 0 - 127 */
     756                main_vol = chan->control[MIDI_CTL_MSB_MAIN_VOLUME];
     757                vol = (vp->velocity * main_vol * expression_vol) / (127*127);
     758                vol = vol * vp->reg.amplitude / 127;
     759
     760                LIMITVALUE(vol, 0, 127);
     761
     762                /* calc to attenuation */
     763                vol = snd_sf_vol_table[vol];
     764
     765        } else {
     766                main_vol = chan->control[MIDI_CTL_MSB_MAIN_VOLUME] * vp->reg.amplitude / 127;
     767                LIMITVALUE(main_vol, 0, 127);
     768
     769                vol = voltab1[main_vol] + voltab2[vp->velocity];
     770                vol = (vol * 8) / 3;
     771                vol += vp->reg.attenuation;
     772                vol += ((0x100 - vol) * expressiontab[expression_vol])/128;
     773        }
     774
     775        master_vol = port->chset.gs_master_volume;
     776        LIMITVALUE(master_vol, 0, 127);
     777        vol += snd_sf_vol_table[master_vol];
     778        vol += port->volume_atten;
    788779
    789780#ifdef SNDRV_EMUX_USE_RAW_EFFECT
    790     if (chan->private) {
    791         snd_emux_effect_table_t *fx = chan->private;
    792         vol += fx->val[EMUX_FX_ATTEN];
    793     }
     781        if (chan->private) {
     782                struct snd_emux_effect_table *fx = chan->private;
     783                vol += fx->val[EMUX_FX_ATTEN];
     784        }
    794785#endif
    795786
    796     LIMITVALUE(vol, 0, 255);
    797     if (vp->avol == vol)
    798         return 0; /* value unchanged */
    799 
    800     vp->avol = vol;
    801     if (!SF_IS_DRUM_BANK(get_bank(port, chan))
    802         && LO_BYTE(vp->reg.parm.volatkhld) < 0x7d) {
    803         int atten;
    804         if (vp->velocity < 70)
    805             atten = 70;
    806         else
    807             atten = vp->velocity;
    808         vp->acutoff = (atten * vp->reg.parm.cutoff + 0xa0) >> 7;
    809     } else {
    810         vp->acutoff = vp->reg.parm.cutoff;
    811     }
    812 
    813     return 1; /* value changed */
     787        LIMITVALUE(vol, 0, 255);
     788        if (vp->avol == vol)
     789                return 0; /* value unchanged */
     790
     791        vp->avol = vol;
     792        if (!SF_IS_DRUM_BANK(get_bank(port, chan))
     793            && LO_BYTE(vp->reg.parm.volatkhld) < 0x7d) {
     794                int atten;
     795                if (vp->velocity < 70)
     796                        atten = 70;
     797                else
     798                        atten = vp->velocity;
     799                vp->acutoff = (atten * vp->reg.parm.cutoff + 0xa0) >> 7;
     800        } else {
     801                vp->acutoff = vp->reg.parm.cutoff;
     802        }
     803
     804        return 1; /* value changed */
    814805}
    815806
     
    822813
    823814static int
    824 calc_pitch(snd_emux_voice_t *vp)
    825 {
    826     snd_midi_channel_t *chan = vp->chan;
    827     int offset;
    828 
    829     /* calculate offset */
    830     if (vp->reg.fixkey >= 0) {
    831         offset = (vp->reg.fixkey - vp->reg.root) * 4096 / 12;
    832     } else {
    833         offset = (vp->note - vp->reg.root) * 4096 / 12;
    834     }
    835     offset = (offset * vp->reg.scaleTuning) / 100;
    836     offset += vp->reg.tune * 4096 / 1200;
    837     if (chan->midi_pitchbend != 0) {
    838         /* (128 * 8192: 1 semitone) ==> (4096: 12 semitones) */
    839         offset += chan->midi_pitchbend * chan->gm_rpn_pitch_bend_range / 3072;
    840     }
    841 
    842     /* tuning via RPN:
    843     *   coarse = -8192 to 8192 (100 cent per 128)
    844     *   fine = -8192 to 8192 (max=100cent)
    845     */
    846     /* 4096 = 1200 cents in emu8000 parameter */
    847     offset += chan->gm_rpn_coarse_tuning * 4096 / (12 * 128);
    848     offset += chan->gm_rpn_fine_tuning / 24;
     815calc_pitch(struct snd_emux_voice *vp)
     816{
     817        struct snd_midi_channel *chan = vp->chan;
     818        int offset;
     819
     820        /* calculate offset */
     821        if (vp->reg.fixkey >= 0) {
     822                offset = (vp->reg.fixkey - vp->reg.root) * 4096 / 12;
     823        } else {
     824                offset = (vp->note - vp->reg.root) * 4096 / 12;
     825        }
     826        offset = (offset * vp->reg.scaleTuning) / 100;
     827        offset += vp->reg.tune * 4096 / 1200;
     828        if (chan->midi_pitchbend != 0) {
     829                /* (128 * 8192: 1 semitone) ==> (4096: 12 semitones) */
     830                offset += chan->midi_pitchbend * chan->gm_rpn_pitch_bend_range / 3072;
     831        }
     832
     833        /* tuning via RPN:
     834        *   coarse = -8192 to 8192 (100 cent per 128)
     835        *   fine = -8192 to 8192 (max=100cent)
     836        */
     837        /* 4096 = 1200 cents in emu8000 parameter */
     838        offset += chan->gm_rpn_coarse_tuning * 4096 / (12 * 128);
     839        offset += chan->gm_rpn_fine_tuning / 24;
    849840
    850841#ifdef SNDRV_EMUX_USE_RAW_EFFECT
    851     /* add initial pitch correction */
    852     if (chan->private) {
    853         snd_emux_effect_table_t *fx = chan->private;
    854         if (fx->flag[EMUX_FX_INIT_PITCH])
    855             offset += fx->val[EMUX_FX_INIT_PITCH];
    856     }
     842        /* add initial pitch correction */
     843        if (chan->private) {
     844                struct snd_emux_effect_table *fx = chan->private;
     845                if (fx->flag[EMUX_FX_INIT_PITCH])
     846                        offset += fx->val[EMUX_FX_INIT_PITCH];
     847        }
    857848#endif
    858849
    859     /* 0xe000: root pitch */
    860     offset += 0xe000 + vp->reg.rate_offset;
    861     offset += vp->emu->pitch_shift;
    862     LIMITVALUE(offset, 0, 0xffff);
    863     if (offset == vp->apitch)
    864         return 0; /* unchanged */
    865     vp->apitch = offset;
    866     return 1; /* value changed */
     850        /* 0xe000: root pitch */
     851        offset += 0xe000 + vp->reg.rate_offset;
     852        offset += vp->emu->pitch_shift;
     853        LIMITVALUE(offset, 0, 0xffff);
     854        if (offset == vp->apitch)
     855                return 0; /* unchanged */
     856        vp->apitch = offset;
     857        return 1; /* value changed */
    867858}
    868859
     
    871862 */
    872863static int
    873 get_bank(snd_emux_port_t *port, snd_midi_channel_t *chan)
    874 {
    875     int val;
    876 
    877     switch (port->chset.midi_mode) {
    878     case SNDRV_MIDI_MODE_XG:
    879         val = chan->control[MIDI_CTL_MSB_BANK];
    880         if (val == 127)
    881             return 128; /* return drum bank */
    882         return chan->control[MIDI_CTL_LSB_BANK];
    883 
    884     case SNDRV_MIDI_MODE_GS:
    885         if (chan->drum_channel)
    886             return 128;
    887         /* ignore LSB (bank map) */
    888         return chan->control[MIDI_CTL_MSB_BANK];
    889 
    890     default:
    891         if (chan->drum_channel)
    892             return 128;
    893         return chan->control[MIDI_CTL_MSB_BANK];
    894     }
     864get_bank(struct snd_emux_port *port, struct snd_midi_channel *chan)
     865{
     866        int val;
     867
     868        switch (port->chset.midi_mode) {
     869        case SNDRV_MIDI_MODE_XG:
     870                val = chan->control[MIDI_CTL_MSB_BANK];
     871                if (val == 127)
     872                        return 128; /* return drum bank */
     873                return chan->control[MIDI_CTL_LSB_BANK];
     874
     875        case SNDRV_MIDI_MODE_GS:
     876                if (chan->drum_channel)
     877                        return 128;
     878                /* ignore LSB (bank map) */
     879                return chan->control[MIDI_CTL_MSB_BANK];
     880               
     881        default:
     882                if (chan->drum_channel)
     883                        return 128;
     884                return chan->control[MIDI_CTL_MSB_BANK];
     885        }
    895886}
    896887
     
    900891 */
    901892static int
    902 get_zone(snd_emux_t *emu, snd_emux_port_t *port,
    903          int *notep, int vel, snd_midi_channel_t *chan, snd_sf_zone_t **table)
    904 {
    905     int preset, bank, def_preset, def_bank;
    906 
    907     bank = get_bank(port, chan);
    908     preset = chan->midi_program;
    909 
    910     if (SF_IS_DRUM_BANK(bank)) {
    911         def_preset = port->ctrls[EMUX_MD_DEF_DRUM];
    912         def_bank = bank;
    913     } else {
    914         def_preset = preset;
    915         def_bank = port->ctrls[EMUX_MD_DEF_BANK];
    916     }
    917 
    918     return snd_soundfont_search_zone(emu->sflist, notep, vel, preset, bank,
    919                                      def_preset, def_bank,
    920                                      table, SNDRV_EMUX_MAX_MULTI_VOICES);
     893get_zone(struct snd_emux *emu, struct snd_emux_port *port,
     894         int *notep, int vel, struct snd_midi_channel *chan,
     895         struct snd_sf_zone **table)
     896{
     897        int preset, bank, def_preset, def_bank;
     898
     899        bank = get_bank(port, chan);
     900        preset = chan->midi_program;
     901
     902        if (SF_IS_DRUM_BANK(bank)) {
     903                def_preset = port->ctrls[EMUX_MD_DEF_DRUM];
     904                def_bank = bank;
     905        } else {
     906                def_preset = preset;
     907                def_bank = port->ctrls[EMUX_MD_DEF_BANK];
     908        }
     909
     910        return snd_soundfont_search_zone(emu->sflist, notep, vel, preset, bank,
     911                                         def_preset, def_bank,
     912                                         table, SNDRV_EMUX_MAX_MULTI_VOICES);
    921913}
    922914
     
    924916 */
    925917void
    926 snd_emux_init_voices(snd_emux_t *emu)
    927 {
    928     snd_emux_voice_t *vp;
    929     int i;
    930     unsigned long flags;
    931 
    932     spin_lock_irqsave(&emu->voice_lock, flags);
    933     for (i = 0; i < emu->max_voices; i++) {
    934         vp = &emu->voices[i];
    935         vp->ch = -1; /* not used */
    936         vp->state = SNDRV_EMUX_ST_OFF;
    937         vp->chan = NULL;
    938         vp->port = NULL;
    939         vp->time = 0;
    940         vp->emu = emu;
    941         vp->hw = emu->hw;
    942     }
    943     spin_unlock_irqrestore(&emu->voice_lock, flags);
    944 }
    945 
    946 /*
    947  */
    948 void snd_emux_lock_voice(snd_emux_t *emu, int voice)
    949 {
    950     unsigned long flags;
    951 
    952     spin_lock_irqsave(&emu->voice_lock, flags);
    953     if (emu->voices[voice].state == SNDRV_EMUX_ST_OFF)
    954         emu->voices[voice].state = SNDRV_EMUX_ST_LOCKED;
    955     else
    956         snd_printk("invalid voice for lock %d (state = %x)\n",
    957                    voice, emu->voices[voice].state);
    958     spin_unlock_irqrestore(&emu->voice_lock, flags);
    959 }
    960 
    961 /*
    962  */
    963 void snd_emux_unlock_voice(snd_emux_t *emu, int voice)
    964 {
    965     unsigned long flags;
    966 
    967     spin_lock_irqsave(&emu->voice_lock, flags);
    968     if (emu->voices[voice].state == SNDRV_EMUX_ST_LOCKED)
    969         emu->voices[voice].state = SNDRV_EMUX_ST_OFF;
    970     else
    971         snd_printk("invalid voice for unlock %d (state = %x)\n",
    972                    voice, emu->voices[voice].state);
    973     spin_unlock_irqrestore(&emu->voice_lock, flags);
    974 }
     918snd_emux_init_voices(struct snd_emux *emu)
     919{
     920        struct snd_emux_voice *vp;
     921        int i;
     922        unsigned long flags;
     923
     924        spin_lock_irqsave(&emu->voice_lock, flags);
     925        for (i = 0; i < emu->max_voices; i++) {
     926                vp = &emu->voices[i];
     927                vp->ch = -1; /* not used */
     928                vp->state = SNDRV_EMUX_ST_OFF;
     929                vp->chan = NULL;
     930                vp->port = NULL;
     931                vp->time = 0;
     932                vp->emu = emu;
     933                vp->hw = emu->hw;
     934        }
     935        spin_unlock_irqrestore(&emu->voice_lock, flags);
     936}
     937
     938/*
     939 */
     940void snd_emux_lock_voice(struct snd_emux *emu, int voice)
     941{
     942        unsigned long flags;
     943
     944        spin_lock_irqsave(&emu->voice_lock, flags);
     945        if (emu->voices[voice].state == SNDRV_EMUX_ST_OFF)
     946                emu->voices[voice].state = SNDRV_EMUX_ST_LOCKED;
     947        else
     948                snd_printk("invalid voice for lock %d (state = %x)\n",
     949                           voice, emu->voices[voice].state);
     950        spin_unlock_irqrestore(&emu->voice_lock, flags);
     951}
     952
     953/*
     954 */
     955void snd_emux_unlock_voice(struct snd_emux *emu, int voice)
     956{
     957        unsigned long flags;
     958
     959        spin_lock_irqsave(&emu->voice_lock, flags);
     960        if (emu->voices[voice].state == SNDRV_EMUX_ST_LOCKED)
     961                emu->voices[voice].state = SNDRV_EMUX_ST_OFF;
     962        else
     963                snd_printk("invalid voice for unlock %d (state = %x)\n",
     964                           voice, emu->voices[voice].state);
     965        spin_unlock_irqrestore(&emu->voice_lock, flags);
     966}
  • GPL/trunk/alsa-kernel/synth/emux/emux_voice.h

    r33 r34  
    3030
    3131/* Prototypes for emux_seq.c */
    32 int snd_emux_init_seq(snd_emux_t *emu, snd_card_t *card, int index);
    33 void snd_emux_detach_seq(snd_emux_t *emu);
    34 snd_emux_port_t *snd_emux_create_port(snd_emux_t *emu, char *name, int max_channels, int type, snd_seq_port_callback_t *callback);
    35 void snd_emux_reset_port(snd_emux_port_t *port);
    36 int snd_emux_event_input(snd_seq_event_t *ev, int direct, void *private, int atomic, int hop);
    37 int snd_emux_inc_count(snd_emux_t *emu);
    38 void snd_emux_dec_count(snd_emux_t *emu);
    39 int snd_emux_init_virmidi(snd_emux_t *emu, snd_card_t *card);
    40 int snd_emux_delete_virmidi(snd_emux_t *emu);
     32int snd_emux_init_seq(struct snd_emux *emu, struct snd_card *card, int index);
     33void snd_emux_detach_seq(struct snd_emux *emu);
     34struct snd_emux_port *snd_emux_create_port(struct snd_emux *emu, char *name,
     35                                           int max_channels, int type,
     36                                           struct snd_seq_port_callback *callback);
     37void snd_emux_reset_port(struct snd_emux_port *port);
     38int snd_emux_event_input(struct snd_seq_event *ev, int direct, void *private,
     39                         int atomic, int hop);
     40int snd_emux_inc_count(struct snd_emux *emu);
     41void snd_emux_dec_count(struct snd_emux *emu);
     42int snd_emux_init_virmidi(struct snd_emux *emu, struct snd_card *card);
     43int snd_emux_delete_virmidi(struct snd_emux *emu);
    4144
    4245/* Prototypes for emux_synth.c */
    43 void snd_emux_init_voices(snd_emux_t *emu);
     46void snd_emux_init_voices(struct snd_emux *emu);
    4447
    4548void snd_emux_note_on(void *p, int note, int vel, struct snd_midi_channel *chan);
    4649void snd_emux_note_off(void *p, int note, int vel, struct snd_midi_channel *chan);
    4750void snd_emux_key_press(void *p, int note, int vel, struct snd_midi_channel *chan);
    48 void snd_emux_terminate_note(void *p, int note, snd_midi_channel_t *chan);
     51void snd_emux_terminate_note(void *p, int note, struct snd_midi_channel *chan);
    4952void snd_emux_control(void *p, int type, struct snd_midi_channel *chan);
    5053
    51 void snd_emux_sounds_off_all(snd_emux_port_t *port);
    52 void snd_emux_update_channel(snd_emux_port_t *port, snd_midi_channel_t *chan, int update);
    53 void snd_emux_update_port(snd_emux_port_t *port, int update);
     54void snd_emux_sounds_off_all(struct snd_emux_port *port);
     55void snd_emux_update_channel(struct snd_emux_port *port,
     56                             struct snd_midi_channel *chan, int update);
     57void snd_emux_update_port(struct snd_emux_port *port, int update);
    5458
    5559void snd_emux_timer_callback(unsigned long data);
     
    5761/* emux_effect.c */
    5862#ifdef SNDRV_EMUX_USE_RAW_EFFECT
    59 void snd_emux_create_effect(snd_emux_port_t *p);
    60 void snd_emux_delete_effect(snd_emux_port_t *p);
    61 void snd_emux_clear_effect(snd_emux_port_t *p);
    62 void snd_emux_setup_effect(snd_emux_voice_t *vp);
    63 void snd_emux_send_effect_oss(snd_emux_port_t *port, snd_midi_channel_t *chan, int type, int val);
    64 void snd_emux_send_effect(snd_emux_port_t *port, snd_midi_channel_t *chan, int type, int val, int mode);
     63void snd_emux_create_effect(struct snd_emux_port *p);
     64void snd_emux_delete_effect(struct snd_emux_port *p);
     65void snd_emux_clear_effect(struct snd_emux_port *p);
     66void snd_emux_setup_effect(struct snd_emux_voice *vp);
     67void snd_emux_send_effect_oss(struct snd_emux_port *port,
     68                              struct snd_midi_channel *chan, int type, int val);
     69void snd_emux_send_effect(struct snd_emux_port *port,
     70                          struct snd_midi_channel *chan, int type, int val, int mode);
    6571#endif
    6672
    6773/* emux_nrpn.c */
    68 void snd_emux_sysex(void *private_data, unsigned char *buf, int len, int parsed, snd_midi_channel_set_t *chset);
    69 int snd_emux_xg_control(snd_emux_port_t *port, snd_midi_channel_t *chan, int param);
    70 void snd_emux_nrpn(void *private_data, snd_midi_channel_t *chan, snd_midi_channel_set_t *chset);
     74void snd_emux_sysex(void *private_data, unsigned char *buf, int len,
     75                    int parsed, struct snd_midi_channel_set *chset);
     76int snd_emux_xg_control(struct snd_emux_port *port,
     77                        struct snd_midi_channel *chan, int param);
     78void snd_emux_nrpn(void *private_data, struct snd_midi_channel *chan,
     79                   struct snd_midi_channel_set *chset);
    7180
    7281/* emux_oss.c */
    73 void snd_emux_init_seq_oss(snd_emux_t *emu);
    74 void snd_emux_detach_seq_oss(snd_emux_t *emu);
     82void snd_emux_init_seq_oss(struct snd_emux *emu);
     83void snd_emux_detach_seq_oss(struct snd_emux *emu);
    7584
    7685/* emux_proc.c */
    7786#ifdef CONFIG_PROC_FS
    78 void snd_emux_proc_init(snd_emux_t *emu, snd_card_t *card, int device);
    79 void snd_emux_proc_free(snd_emux_t *emu);
     87void snd_emux_proc_init(struct snd_emux *emu, struct snd_card *card, int device);
     88void snd_emux_proc_free(struct snd_emux *emu);
    8089#endif
    8190
    8291#define STATE_IS_PLAYING(s) ((s) & SNDRV_EMUX_ST_ON)
    8392
     93/* emux_hwdep.c */
     94int snd_emux_init_hwdep(struct snd_emux *emu);
     95void snd_emux_delete_hwdep(struct snd_emux *emu);
     96
    8497#endif
  • GPL/trunk/alsa-kernel/synth/emux/soundfont.c

    r33 r34  
    2626 * Everything may change when there is an alsa way of doing things.
    2727 */
    28 #define __NO_VERSION__
    2928#include <sound/driver.h>
    3029#include <asm/uaccess.h>
     
    3231#include <sound/core.h>
    3332#include <sound/soundfont.h>
     33#include <sound/seq_oss_legacy.h>
    3434
    3535/* Prototypes for static functions */
    3636
    37 static int open_patch(snd_sf_list_t *sflist, const char *data, int count, int client);
    38 static snd_soundfont_t *newsf(snd_sf_list_t *sflist, int type, char *name);
    39 static int is_identical_font(snd_soundfont_t *sf, int type, unsigned char *name);
    40 static int close_patch(snd_sf_list_t *sflist);
    41 static int probe_data(snd_sf_list_t *sflist, int sample_id);
    42 static void set_zone_counter(snd_sf_list_t *sflist, snd_soundfont_t *sf, snd_sf_zone_t *zp);
    43 static snd_sf_zone_t *sf_zone_new(snd_sf_list_t *sflist, snd_soundfont_t *sf);
    44 static void set_sample_counter(snd_sf_list_t *sflist, snd_soundfont_t *sf, snd_sf_sample_t *sp);
    45 static snd_sf_sample_t *sf_sample_new(snd_sf_list_t *sflist, snd_soundfont_t *sf);
    46 static void sf_sample_delete(snd_sf_list_t *sflist, snd_soundfont_t *sf, snd_sf_sample_t *sp);
    47 static int load_map(snd_sf_list_t *sflist, const void *data, int count);
    48 static int load_info(snd_sf_list_t *sflist, const void *data, long count);
    49 static int remove_info(snd_sf_list_t *sflist, snd_soundfont_t *sf, int bank, int instr);
    50 static void init_voice_info(soundfont_voice_info_t *avp);
    51 static void init_voice_parm(soundfont_voice_parm_t *pp);
    52 static snd_sf_sample_t *set_sample(snd_soundfont_t *sf, soundfont_voice_info_t *avp);
    53 static snd_sf_sample_t *find_sample(snd_soundfont_t *sf, int sample_id);
    54 static int load_data(snd_sf_list_t *sflist, const void *data, long count);
    55 static void rebuild_presets(snd_sf_list_t *sflist);
    56 static void add_preset(snd_sf_list_t *sflist, snd_sf_zone_t *cur);
    57 static void delete_preset(snd_sf_list_t *sflist, snd_sf_zone_t *zp);
    58 static snd_sf_zone_t *search_first_zone(snd_sf_list_t *sflist, int bank, int preset, int key);
    59 static int search_zones(snd_sf_list_t *sflist, int *notep, int vel, int preset, int bank, snd_sf_zone_t **table, int max_layers, int level);
     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);
    6071static int get_index(int bank, int instr, int key);
    61 static void snd_sf_init(snd_sf_list_t *sflist);
    62 static void snd_sf_clear(snd_sf_list_t *sflist);
     72static void snd_sf_init(struct snd_sf_list *sflist);
     73static void snd_sf_clear(struct snd_sf_list *sflist);
    6374
    6475/*
    6576 * lock access to sflist
    6677 */
    67 static int
    68     lock_preset(snd_sf_list_t *sflist, int nonblock)
    69 {
    70     unsigned long flags;
    71     spin_lock_irqsave(&sflist->lock, flags);
    72     if (sflist->sf_locked && nonblock) {
    73         spin_unlock_irqrestore(&sflist->lock, flags);
    74         return -EBUSY;
    75     }
    76     spin_unlock_irqrestore(&sflist->lock, flags);
    77     down(&sflist->presets_mutex);
    78     sflist->sf_locked = 1;
    79     return 0;
     78static void
     79lock_preset(struct snd_sf_list *sflist)
     80{
     81        unsigned long flags;
     82        down(&sflist->presets_mutex);
     83        spin_lock_irqsave(&sflist->lock, flags);
     84        sflist->presets_locked = 1;
     85        spin_unlock_irqrestore(&sflist->lock, flags);
    8086}
    8187
     
    8591 */
    8692static void
    87 unlock_preset(snd_sf_list_t *sflist)
    88 {
    89     up(&sflist->presets_mutex);
    90     sflist->sf_locked = 0;
     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        up(&sflist->presets_mutex);
    91100}
    92101
     
    96105 */
    97106int
    98 snd_soundfont_close_check(snd_sf_list_t *sflist, int client)
    99 {
    100     unsigned long flags;
    101     spin_lock_irqsave(&sflist->lock, flags);
    102     if (sflist->open_client == client)  {
    103         spin_unlock_irqrestore(&sflist->lock, flags);
    104         return close_patch(sflist);
    105     }
    106     spin_unlock_irqrestore(&sflist->lock, flags);
    107     return 0;
     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;
    108117}
    109118
     
    118127 */
    119128int
    120 snd_soundfont_load(snd_sf_list_t *sflist, const void *data, long count, int client)
    121 {
    122     soundfont_patch_info_t patch;
    123     unsigned long flags;
    124     int  rc;
    125 
    126     if (count < sizeof(patch)) {
    127         snd_printk("patch record too small %ld\n", count);
    128         return -EINVAL;
    129     }
    130     if (copy_from_user(&patch, data, sizeof(patch)))
    131         return -EFAULT;
    132 
    133     count -= sizeof(patch);
    134 #ifdef TARGET_OS2
    135     data = (char *)data + sizeof(patch);
    136 #else
    137     data += sizeof(patch);
    138 #endif
    139     if (patch.key != SNDRV_OSS_SOUNDFONT_PATCH) {
    140         snd_printk("'The wrong kind of patch' %x\n", patch.key);
    141         return -EINVAL;
    142     }
    143     if (count < patch.len) {
    144         snd_printk("Patch too short %ld, need %d\n", count, patch.len);
    145         return -EINVAL;
    146     }
    147     if (patch.len < 0) {
    148         snd_printk("poor length %d\n", patch.len);
    149         return -EINVAL;
    150     }
    151 
    152     if (patch.type == SNDRV_SFNT_OPEN_PATCH) {
    153         /* grab sflist to open */
    154         lock_preset(sflist, 0);
    155         rc = open_patch(sflist, data, count, client);
    156         unlock_preset(sflist);
    157         return rc;
    158     }
    159 
    160     /* check if other client already opened patch */
    161     spin_lock_irqsave(&sflist->lock, flags);
    162     if (sflist->open_client != client) {
    163         spin_unlock_irqrestore(&sflist->lock, flags);
    164         return -EBUSY;
    165     }
    166     spin_unlock_irqrestore(&sflist->lock, flags);
    167 
    168     lock_preset(sflist, 0);
    169     rc = -EINVAL;
    170     switch (patch.type) {
    171     case SNDRV_SFNT_LOAD_INFO:
    172         rc = load_info(sflist, data, count);
    173         break;
    174     case SNDRV_SFNT_LOAD_DATA:
    175         rc = load_data(sflist, data, count);
    176         break;
    177     case SNDRV_SFNT_CLOSE_PATCH:
    178         rc = close_patch(sflist);
    179         break;
    180     case SNDRV_SFNT_REPLACE_DATA:
    181         /*rc = replace_data(&patch, data, count);*/
    182         break;
    183     case SNDRV_SFNT_MAP_PRESET:
    184         rc = load_map(sflist, data, count);
    185         break;
    186     case SNDRV_SFNT_PROBE_DATA:
    187         rc = probe_data(sflist, patch.optarg);
    188         break;
    189     case SNDRV_SFNT_REMOVE_INFO:
    190         /* patch must be opened */
    191         if (sflist->currsf) {
    192             snd_printk("soundfont: remove_info: patch not opened\n");
    193             rc = -EINVAL;
    194         } else {
    195             int bank, instr;
    196             bank = ((unsigned short)patch.optarg >> 8) & 0xff;
    197             instr = (unsigned short)patch.optarg & 0xff;
    198             if (! remove_info(sflist, sflist->currsf, bank, instr))
    199                 rc = -EINVAL;
    200             else
    201                 rc = 0;
    202         }
    203         break;
    204     }
    205     unlock_preset(sflist);
    206 
    207     return rc;
     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("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        (char*)data += sizeof(patch);
     145
     146        if (patch.key != SNDRV_OSS_SOUNDFONT_PATCH) {
     147                snd_printk("'The wrong kind of patch' %x\n", patch.key);
     148                return -EINVAL;
     149        }
     150        if (count < patch.len) {
     151                snd_printk("Patch too short %ld, need %d\n", count, patch.len);
     152                return -EINVAL;
     153        }
     154        if (patch.len < 0) {
     155                snd_printk("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("soundfont: remove_info: patch not opened\n");
     200                        rc = -EINVAL;
     201                } else {
     202                        int bank, instr;
     203                        bank = ((unsigned short)patch.optarg >> 8) & 0xff;
     204                        instr = (unsigned short)patch.optarg & 0xff;
     205                        if (! remove_info(sflist, sflist->currsf, bank, instr))
     206                                rc = -EINVAL;
     207                        else
     208                                rc = 0;
     209                }
     210                break;
     211        }
     212        unlock_preset(sflist);
     213
     214        return rc;
    208215}
    209216
     
    213220is_special_type(int type)
    214221{
    215     type &= 0x0f;
    216     return (type == SNDRV_SFNT_PAT_TYPE_GUS ||
    217             type == SNDRV_SFNT_PAT_TYPE_MAP);
     222        type &= 0x0f;
     223        return (type == SNDRV_SFNT_PAT_TYPE_GUS ||
     224                type == SNDRV_SFNT_PAT_TYPE_MAP);
    218225}
    219226
     
    221228/* open patch; create sf list */
    222229static int
    223 open_patch(snd_sf_list_t *sflist, const char *data, int count, int client)
    224 {
    225     soundfont_open_parm_t parm;
    226     snd_soundfont_t *sf;
    227     unsigned long flags;
    228 
    229     spin_lock_irqsave(&sflist->lock, flags);
    230     if (sflist->open_client >= 0 || sflist->currsf) {
    231         spin_unlock_irqrestore(&sflist->lock, flags);
    232         return -EBUSY;
    233     }
    234     spin_unlock_irqrestore(&sflist->lock, flags);
    235 
    236     if (copy_from_user(&parm, data, sizeof(parm)))
    237         return -EFAULT;
    238 
    239     if (is_special_type(parm.type)) {
    240         parm.type |= SNDRV_SFNT_PAT_SHARED;
    241         sf = newsf(sflist, parm.type, NULL);
    242     } else
    243         sf = newsf(sflist, parm.type, parm.name);
    244     if (sf == NULL) {
    245         return -ENOMEM;
    246     }
    247 
    248     sflist->open_client = client;
    249     sflist->currsf = sf;
    250 
    251     return 0;
     230open_patch(struct snd_sf_list *sflist, const char __user *data,
     231           int count, int client)
     232{
     233        struct soundfont_open_parm parm;
     234        struct snd_soundfont *sf;
     235        unsigned long flags;
     236
     237        spin_lock_irqsave(&sflist->lock, flags);
     238        if (sflist->open_client >= 0 || sflist->currsf) {
     239                spin_unlock_irqrestore(&sflist->lock, flags);
     240                return -EBUSY;
     241        }
     242        spin_unlock_irqrestore(&sflist->lock, flags);
     243
     244        if (copy_from_user(&parm, data, sizeof(parm)))
     245                return -EFAULT;
     246
     247        if (is_special_type(parm.type)) {
     248                parm.type |= SNDRV_SFNT_PAT_SHARED;
     249                sf = newsf(sflist, parm.type, NULL);
     250        } else
     251                sf = newsf(sflist, parm.type, parm.name);
     252        if (sf == NULL) {
     253                return -ENOMEM;
     254        }
     255
     256        spin_lock_irqsave(&sflist->lock, flags);
     257        sflist->open_client = client;
     258        sflist->currsf = sf;
     259        spin_unlock_irqrestore(&sflist->lock, flags);
     260
     261        return 0;
    252262}
    253263
     
    255265 * Allocate a new soundfont structure.
    256266 */
    257 static snd_soundfont_t *
    258 newsf(snd_sf_list_t *sflist, int type, char *name)
    259 {
    260     snd_soundfont_t *sf;
    261 
    262     /* check the shared fonts */
    263     if (type & SNDRV_SFNT_PAT_SHARED) {
    264         for (sf = sflist->fonts; sf; sf = sf->next) {
    265             if (is_identical_font(sf, type, name)) {
    266                 return sf;
    267             }
    268         }
    269     }
    270 
    271     /* not found -- create a new one */
    272     sf = kcalloc(1, sizeof(*sf), GFP_KERNEL);
    273     if (sf == NULL)
    274         return NULL;
    275     sf->id = sflist->fonts_size;
    276     sflist->fonts_size++;
    277 
    278     /* prepend this record */
    279     sf->next = sflist->fonts;
    280     sflist->fonts = sf;
    281 
    282     sf->type = type;
    283     sf->zones = NULL;
    284     sf->samples = NULL;
    285     if (name)
    286         memcpy(sf->name, name, SNDRV_SFNT_PATCH_NAME_LEN);
    287 
    288     return sf;
     267static struct snd_soundfont *
     268newsf(struct snd_sf_list *sflist, int type, char *name)
     269{
     270        struct snd_soundfont *sf;
     271
     272        /* check the shared fonts */
     273        if (type & SNDRV_SFNT_PAT_SHARED) {
     274                for (sf = sflist->fonts; sf; sf = sf->next) {
     275                        if (is_identical_font(sf, type, name)) {
     276                                return sf;
     277                        }
     278                }
     279        }
     280
     281        /* not found -- create a new one */
     282        sf = kzalloc(sizeof(*sf), GFP_KERNEL);
     283        if (sf == NULL)
     284                return NULL;
     285        sf->id = sflist->fonts_size;
     286        sflist->fonts_size++;
     287
     288        /* prepend this record */
     289        sf->next = sflist->fonts;
     290        sflist->fonts = sf;
     291
     292        sf->type = type;
     293        sf->zones = NULL;
     294        sf->samples = NULL;
     295        if (name)
     296                memcpy(sf->name, name, SNDRV_SFNT_PATCH_NAME_LEN);
     297
     298        return sf;
    289299}
    290300
    291301/* check if the given name matches to the existing list */
    292302static int
    293 is_identical_font(snd_soundfont_t *sf, int type, unsigned char *name)
    294 {
    295     return ((sf->type & SNDRV_SFNT_PAT_SHARED) &&
    296             (sf->type & 0x0f) == (type & 0x0f) &&
    297             (name == NULL ||
    298             memcmp(sf->name, name, SNDRV_SFNT_PATCH_NAME_LEN) == 0));
     303is_identical_font(struct snd_soundfont *sf, int type, unsigned char *name)
     304{
     305        return ((sf->type & SNDRV_SFNT_PAT_SHARED) &&
     306                (sf->type & 0x0f) == (type & 0x0f) &&
     307                (name == NULL ||
     308                memcmp(sf->name, name, SNDRV_SFNT_PATCH_NAME_LEN) == 0));
    299309}
    300310
     
    303313 */
    304314static int
    305 close_patch(snd_sf_list_t *sflist)
    306 {
    307     sflist->currsf = NULL;
    308     sflist->open_client = -1;
    309 
    310     rebuild_presets(sflist);
    311 
    312     return 0;
     315close_patch(struct snd_sf_list *sflist)
     316{
     317        unsigned long flags;
     318
     319        spin_lock_irqsave(&sflist->lock, flags);
     320        sflist->currsf = NULL;
     321        sflist->open_client = -1;
     322        spin_unlock_irqrestore(&sflist->lock, flags);
     323
     324        rebuild_presets(sflist);
     325
     326        return 0;
    313327
    314328}
     
    316330/* probe sample in the current list -- nothing to be loaded */
    317331static int
    318 probe_data(snd_sf_list_t *sflist, int sample_id)
    319 {
    320     /* patch must be opened */
    321     if (sflist->currsf) {
    322         /* search the specified sample by optarg */
    323         if (find_sample(sflist->currsf, sample_id))
    324             return 0;
    325     }
    326     return -EINVAL;
     332probe_data(struct snd_sf_list *sflist, int sample_id)
     333{
     334        /* patch must be opened */
     335        if (sflist->currsf) {
     336                /* search the specified sample by optarg */
     337                if (find_sample(sflist->currsf, sample_id))
     338                        return 0;
     339        }
     340        return -EINVAL;
    327341}
    328342
     
    331345 */
    332346static void
    333 set_zone_counter(snd_sf_list_t *sflist, snd_soundfont_t *sf, snd_sf_zone_t *zp)
    334 {
    335     zp->counter = sflist->zone_counter++;
    336     if (sf->type & SNDRV_SFNT_PAT_LOCKED)
    337         sflist->zone_locked = sflist->zone_counter;
     347set_zone_counter(struct snd_sf_list *sflist, struct snd_soundfont *sf,
     348                 struct snd_sf_zone *zp)
     349{
     350        zp->counter = sflist->zone_counter++;
     351        if (sf->type & SNDRV_SFNT_PAT_LOCKED)
     352                sflist->zone_locked = sflist->zone_counter;
    338353}
    339354
     
    341356 * allocate a new zone record
    342357 */
    343 static snd_sf_zone_t *
    344 sf_zone_new(snd_sf_list_t *sflist, snd_soundfont_t *sf)
    345 {
    346     snd_sf_zone_t *zp;
    347 
    348     if ((zp = kcalloc(1, sizeof(*zp), GFP_KERNEL)) == NULL)
    349         return NULL;
    350     zp->next = sf->zones;
    351     sf->zones = zp;
    352 
    353     init_voice_info(&zp->v);
    354 
    355     set_zone_counter(sflist, sf, zp);
    356     return zp;
     358static struct snd_sf_zone *
     359sf_zone_new(struct snd_sf_list *sflist, struct snd_soundfont *sf)
     360{
     361        struct snd_sf_zone *zp;
     362
     363        if ((zp = kzalloc(sizeof(*zp), GFP_KERNEL)) == NULL)
     364                return NULL;
     365        zp->next = sf->zones;
     366        sf->zones = zp;
     367
     368        init_voice_info(&zp->v);
     369
     370        set_zone_counter(sflist, sf, zp);
     371        return zp;
    357372}
    358373
     
    362377 */
    363378static void
    364 set_sample_counter(snd_sf_list_t *sflist, snd_soundfont_t *sf, snd_sf_sample_t *sp)
    365 {
    366     sp->counter = sflist->sample_counter++;
    367     if (sf->type & SNDRV_SFNT_PAT_LOCKED)
    368         sflist->sample_locked = sflist->sample_counter;
     379set_sample_counter(struct snd_sf_list *sflist, struct snd_soundfont *sf,
     380                   struct snd_sf_sample *sp)
     381{
     382        sp->counter = sflist->sample_counter++;
     383        if (sf->type & SNDRV_SFNT_PAT_LOCKED)
     384                sflist->sample_locked = sflist->sample_counter;
    369385}
    370386
     
    372388 * allocate a new sample list record
    373389 */
    374 static snd_sf_sample_t *
    375 sf_sample_new(snd_sf_list_t *sflist, snd_soundfont_t *sf)
    376 {
    377     snd_sf_sample_t *sp;
    378 
    379     if ((sp = kcalloc(1, sizeof(*sp), GFP_KERNEL)) == NULL)
    380         return NULL;
    381 
    382     sp->next = sf->samples;
    383     sf->samples = sp;
    384 
    385     set_sample_counter(sflist, sf, sp);
    386     return sp;
     390static struct snd_sf_sample *
     391sf_sample_new(struct snd_sf_list *sflist, struct snd_soundfont *sf)
     392{
     393        struct snd_sf_sample *sp;
     394
     395        if ((sp = kzalloc(sizeof(*sp), GFP_KERNEL)) == NULL)
     396                return NULL;
     397
     398        sp->next = sf->samples;
     399        sf->samples = sp;
     400
     401        set_sample_counter(sflist, sf, sp);
     402        return sp;
    387403}
    388404
     
    392408 */
    393409static void
    394 sf_sample_delete(snd_sf_list_t *sflist, snd_soundfont_t *sf, snd_sf_sample_t *sp)
    395 {
    396     /* only last sample is accepted */
    397     if (sp == sf->samples) {
    398         sf->samples = sp->next;
    399         kfree(sp);
    400     }
     410sf_sample_delete(struct snd_sf_list *sflist, struct snd_soundfont *sf,
     411                 struct snd_sf_sample *sp)
     412{
     413        /* only last sample is accepted */
     414        if (sp == sf->samples) {
     415                sf->samples = sp->next;
     416                kfree(sp);
     417        }
    401418}
    402419
     
    404421/* load voice map */
    405422static int
    406 load_map(snd_sf_list_t *sflist, const void *data, int count)
    407 {
    408     snd_sf_zone_t *zp, *prevp;
    409     snd_soundfont_t *sf;
    410     soundfont_voice_map_t map;
    411 
    412     /* get the link info */
    413     if (count < sizeof(map))
    414         return -EINVAL;
    415     if (copy_from_user(&map, data, sizeof(map)))
    416         return -EFAULT;
    417 
    418     if (map.map_instr < 0 || map.map_instr >= SF_MAX_INSTRUMENTS)
    419         return -EINVAL;
    420 
    421     sf = newsf(sflist, SNDRV_SFNT_PAT_TYPE_MAP|SNDRV_SFNT_PAT_SHARED, NULL);
    422     if (sf == NULL)
    423         return -ENOMEM;
    424 
    425     prevp = NULL;
    426     for (zp = sf->zones; zp; prevp = zp, zp = zp->next) {
    427         if (zp->mapped &&
    428             zp->instr == map.map_instr &&
    429             zp->bank == map.map_bank &&
    430             zp->v.low == map.map_key &&
    431             zp->v.start == map.src_instr &&
    432             zp->v.end == map.src_bank &&
    433             zp->v.fixkey == map.src_key) {
    434             /* the same mapping is already present */
    435             /* relink this record to the link head */
    436             if (prevp) {
    437                 prevp->next = zp->next;
    438                 zp->next = sf->zones;
    439                 sf->zones = zp;
    440             }
    441             /* update the counter */
    442             set_zone_counter(sflist, sf, zp);
    443             return 0;
    444         }
    445     }
    446 
    447     /* create a new zone */
    448     if ((zp = sf_zone_new(sflist, sf)) == NULL)
    449         return -ENOMEM;
    450 
    451     zp->bank = map.map_bank;
    452     zp->instr = map.map_instr;
    453     zp->mapped = 1;
    454     if (map.map_key >= 0) {
    455         zp->v.low = map.map_key;
    456         zp->v.high = map.map_key;
    457     }
    458     zp->v.start = map.src_instr;
    459     zp->v.end = map.src_bank;
    460     zp->v.fixkey = map.src_key;
    461     zp->v.sf_id = sf->id;
    462 
    463     add_preset(sflist, zp);
    464 
    465     return 0;
     423load_map(struct snd_sf_list *sflist, const void __user *data, int count)
     424{
     425        struct snd_sf_zone *zp, *prevp;
     426        struct snd_soundfont *sf;
     427        struct soundfont_voice_map map;
     428
     429        /* get the link info */
     430        if (count < (int)sizeof(map))
     431                return -EINVAL;
     432        if (copy_from_user(&map, data, sizeof(map)))
     433                return -EFAULT;
     434
     435        if (map.map_instr < 0 || map.map_instr >= SF_MAX_INSTRUMENTS)
     436                return -EINVAL;
     437       
     438        sf = newsf(sflist, SNDRV_SFNT_PAT_TYPE_MAP|SNDRV_SFNT_PAT_SHARED, NULL);
     439        if (sf == NULL)
     440                return -ENOMEM;
     441
     442        prevp = NULL;
     443        for (zp = sf->zones; zp; prevp = zp, zp = zp->next) {
     444                if (zp->mapped &&
     445                    zp->instr == map.map_instr &&
     446                    zp->bank == map.map_bank &&
     447                    zp->v.low == map.map_key &&
     448                    zp->v.start == map.src_instr &&
     449                    zp->v.end == map.src_bank &&
     450                    zp->v.fixkey == map.src_key) {
     451                        /* the same mapping is already present */
     452                        /* relink this record to the link head */
     453                        if (prevp) {
     454                                prevp->next = zp->next;
     455                                zp->next = sf->zones;
     456                                sf->zones = zp;
     457                        }
     458                        /* update the counter */
     459                        set_zone_counter(sflist, sf, zp);
     460                        return 0;
     461                }
     462        }
     463
     464        /* create a new zone */
     465        if ((zp = sf_zone_new(sflist, sf)) == NULL)
     466                return -ENOMEM;
     467
     468        zp->bank = map.map_bank;
     469        zp->instr = map.map_instr;
     470        zp->mapped = 1;
     471        if (map.map_key >= 0) {
     472                zp->v.low = map.map_key;
     473                zp->v.high = map.map_key;
     474        }
     475        zp->v.start = map.src_instr;
     476        zp->v.end = map.src_bank;
     477        zp->v.fixkey = map.src_key;
     478        zp->v.sf_id = sf->id;
     479
     480        add_preset(sflist, zp);
     481
     482        return 0;
    466483}
    467484
     
    469486/* remove the present instrument layers */
    470487static int
    471 remove_info(snd_sf_list_t *sflist, snd_soundfont_t *sf, int bank, int instr)
    472 {
    473     snd_sf_zone_t *prev, *next, *p;
    474     int removed = 0;
    475 
    476     prev = NULL;
    477     for (p = sf->zones; p; p = next) {
    478         next = p->next;
    479         if (! p->mapped &&
    480             p->bank == bank && p->instr == instr) {
    481             /* remove this layer */
    482             if (prev)
    483                 prev->next = next;
    484             else
    485                 sf->zones = next;
    486             removed++;
    487             kfree(p);
    488         } else
    489             prev = p;
    490     }
    491     if (removed)
    492         rebuild_presets(sflist);
    493     return removed;
     488remove_info(struct snd_sf_list *sflist, struct snd_soundfont *sf,
     489            int bank, int instr)
     490{
     491        struct snd_sf_zone *prev, *next, *p;
     492        int removed = 0;
     493
     494        prev = NULL;
     495        for (p = sf->zones; p; p = next) {
     496                next = p->next;
     497                if (! p->mapped &&
     498                    p->bank == bank && p->instr == instr) {
     499                        /* remove this layer */
     500                        if (prev)
     501                                prev->next = next;
     502                        else
     503                                sf->zones = next;
     504                        removed++;
     505                        kfree(p);
     506                } else
     507                        prev = p;
     508        }
     509        if (removed)
     510                rebuild_presets(sflist);
     511        return removed;
    494512}
    495513
     
    500518 */
    501519static int
    502 load_info(snd_sf_list_t *sflist, const void *data, long count)
    503 {
    504     snd_soundfont_t *sf;
    505     snd_sf_zone_t *zone;
    506     soundfont_voice_rec_hdr_t hdr;
    507     int i;
    508 
    509     /* patch must be opened */
    510     if ((sf = sflist->currsf) == NULL)
    511         return -EINVAL;
    512 
    513     if (is_special_type(sf->type))
    514         return -EINVAL;
    515 
    516     if (count < sizeof(hdr)) {
    517         printk("Soundfont error: invalid patch zone length\n");
    518         return -EINVAL;
    519     }
    520     if (copy_from_user((char*)&hdr, data, sizeof(hdr)))
    521         return -EFAULT;
    522 
    523 #ifdef TARGET_OS2
    524     data = (char *)data + sizeof(hdr);
    525 #else
    526     data += sizeof(hdr);
    527 #endif
    528     count -= sizeof(hdr);
    529 
    530     if (hdr.nvoices <= 0 || hdr.nvoices >= 100) {
    531         printk("Soundfont error: Illegal voice number %d\n", hdr.nvoices);
    532         return -EINVAL;
    533     }
    534 
    535     if (count < sizeof(soundfont_voice_info_t)*hdr.nvoices) {
    536         printk("Soundfont Error: patch length(%ld) is smaller than nvoices(%d)\n",
    537                count, hdr.nvoices);
    538         return -EINVAL;
    539     }
    540 
    541     switch (hdr.write_mode) {
    542     case SNDRV_SFNT_WR_EXCLUSIVE:
    543         /* exclusive mode - if the instrument already exists,
    544          return error */
    545         for (zone = sf->zones; zone; zone = zone->next) {
    546             if (!zone->mapped &&
    547                 zone->bank == hdr.bank &&
    548                 zone->instr == hdr.instr)
    549                 return -EINVAL;
    550         }
    551         break;
    552     case SNDRV_SFNT_WR_REPLACE:
    553         /* replace mode - remove the instrument if it already exists */
    554         remove_info(sflist, sf, hdr.bank, hdr.instr);
    555         break;
    556     }
    557 
    558     for (i = 0; i < hdr.nvoices; i++) {
    559         snd_sf_zone_t tmpzone;
    560 
    561         /* copy awe_voice_info parameters */
    562         if (copy_from_user(&tmpzone.v, data, sizeof(tmpzone.v))) {
    563             return -EFAULT;
    564         }
    565 
    566 #ifdef TARGET_OS2
    567         data = (char *)data + sizeof(tmpzone.v);
    568 #else
    569         data += sizeof(tmpzone.v);
    570 #endif
    571         count -= sizeof(tmpzone.v);
    572 
    573         tmpzone.bank = hdr.bank;
    574         tmpzone.instr = hdr.instr;
    575         tmpzone.mapped = 0;
    576         tmpzone.v.sf_id = sf->id;
    577         if (tmpzone.v.mode & SNDRV_SFNT_MODE_INIT_PARM)
    578             init_voice_parm(&tmpzone.v.parm);
    579 
    580         /* create a new zone */
    581         if ((zone = sf_zone_new(sflist, sf)) == NULL) {
    582             return -ENOMEM;
    583         }
    584 
    585         /* copy the temporary data */
    586         zone->bank = tmpzone.bank;
    587         zone->instr = tmpzone.instr;
    588         zone->v = tmpzone.v;
    589 
    590         /* look up the sample */
    591         zone->sample = set_sample(sf, &zone->v);
    592     }
    593 
    594     return 0;
     520load_info(struct snd_sf_list *sflist, const void __user *data, long count)
     521{
     522        struct snd_soundfont *sf;
     523        struct snd_sf_zone *zone;
     524        struct soundfont_voice_rec_hdr hdr;
     525        int i;
     526
     527        /* patch must be opened */
     528        if ((sf = sflist->currsf) == NULL)
     529                return -EINVAL;
     530
     531        if (is_special_type(sf->type))
     532                return -EINVAL;
     533
     534        if (count < (long)sizeof(hdr)) {
     535                printk("Soundfont error: invalid patch zone length\n");
     536                return -EINVAL;
     537        }
     538        if (copy_from_user((char*)&hdr, data, sizeof(hdr)))
     539                return -EFAULT;
     540       
     541        (char*)data += sizeof(hdr);
     542        count -= sizeof(hdr);
     543
     544        if (hdr.nvoices <= 0 || hdr.nvoices >= 100) {
     545                printk("Soundfont error: Illegal voice number %d\n", hdr.nvoices);
     546                return -EINVAL;
     547        }
     548
     549        if (count < (long)sizeof(struct soundfont_voice_info) * hdr.nvoices) {
     550                printk("Soundfont Error: patch length(%ld) is smaller than nvoices(%d)\n",
     551                       count, hdr.nvoices);
     552                return -EINVAL;
     553        }
     554
     555        switch (hdr.write_mode) {
     556        case SNDRV_SFNT_WR_EXCLUSIVE:
     557                /* exclusive mode - if the instrument already exists,
     558                   return error */
     559                for (zone = sf->zones; zone; zone = zone->next) {
     560                        if (!zone->mapped &&
     561                            zone->bank == hdr.bank &&
     562                            zone->instr == hdr.instr)
     563                                return -EINVAL;
     564                }
     565                break;
     566        case SNDRV_SFNT_WR_REPLACE:
     567                /* replace mode - remove the instrument if it already exists */
     568                remove_info(sflist, sf, hdr.bank, hdr.instr);
     569                break;
     570        }
     571
     572        for (i = 0; i < hdr.nvoices; i++) {
     573                struct snd_sf_zone tmpzone;
     574
     575                /* copy awe_voice_info parameters */
     576                if (copy_from_user(&tmpzone.v, data, sizeof(tmpzone.v))) {
     577                        return -EFAULT;
     578                }
     579
     580                (char*)data += sizeof(tmpzone.v);
     581                count -= sizeof(tmpzone.v);
     582
     583                tmpzone.bank = hdr.bank;
     584                tmpzone.instr = hdr.instr;
     585                tmpzone.mapped = 0;
     586                tmpzone.v.sf_id = sf->id;
     587                if (tmpzone.v.mode & SNDRV_SFNT_MODE_INIT_PARM)
     588                        init_voice_parm(&tmpzone.v.parm);
     589
     590                /* create a new zone */
     591                if ((zone = sf_zone_new(sflist, sf)) == NULL) {
     592                        return -ENOMEM;
     593                }
     594
     595                /* copy the temporary data */
     596                zone->bank = tmpzone.bank;
     597                zone->instr = tmpzone.instr;
     598                zone->v = tmpzone.v;
     599
     600                /* look up the sample */
     601                zone->sample = set_sample(sf, &zone->v);
     602        }
     603
     604        return 0;
    595605}
    596606
     
    598608/* initialize voice_info record */
    599609static void
    600 init_voice_info(soundfont_voice_info_t *avp)
    601 {
    602     memset(avp, 0, sizeof(*avp));
    603 
    604     avp->root = 60;
    605     avp->high = 127;
    606     avp->velhigh = 127;
    607     avp->fixkey = -1;
    608     avp->fixvel = -1;
    609     avp->fixpan = -1;
    610     avp->pan = -1;
    611     avp->amplitude = 127;
    612     avp->scaleTuning = 100;
    613 
    614     init_voice_parm(&avp->parm);
     610init_voice_info(struct soundfont_voice_info *avp)
     611{
     612        memset(avp, 0, sizeof(*avp));
     613
     614        avp->root = 60;
     615        avp->high = 127;
     616        avp->velhigh = 127;
     617        avp->fixkey = -1;
     618        avp->fixvel = -1;
     619        avp->fixpan = -1;
     620        avp->pan = -1;
     621        avp->amplitude = 127;
     622        avp->scaleTuning = 100;
     623
     624        init_voice_parm(&avp->parm);
    615625}
    616626
     
    622632 */
    623633static void
    624 init_voice_parm(soundfont_voice_parm_t *pp)
    625 {
    626     memset(pp, 0, sizeof(*pp));
    627 
    628     pp->moddelay = 0x8000;
    629     pp->modatkhld = 0x7f7f;
    630     pp->moddcysus = 0x7f7f;
    631     pp->modrelease = 0x807f;
    632 
    633     pp->voldelay = 0x8000;
    634     pp->volatkhld = 0x7f7f;
    635     pp->voldcysus = 0x7f7f;
    636     pp->volrelease = 0x807f;
    637 
    638     pp->lfo1delay = 0x8000;
    639     pp->lfo2delay = 0x8000;
    640 
    641     pp->cutoff = 0xff;
    642 }
     634init_voice_parm(struct soundfont_voice_parm *pp)
     635{
     636        memset(pp, 0, sizeof(*pp));
     637
     638        pp->moddelay = 0x8000;
     639        pp->modatkhld = 0x7f7f;
     640        pp->moddcysus = 0x7f7f;
     641        pp->modrelease = 0x807f;
     642
     643        pp->voldelay = 0x8000;
     644        pp->volatkhld = 0x7f7f;
     645        pp->voldcysus = 0x7f7f;
     646        pp->volrelease = 0x807f;
     647
     648        pp->lfo1delay = 0x8000;
     649        pp->lfo2delay = 0x8000;
     650
     651        pp->cutoff = 0xff;
     652}       
    643653
    644654/* search the specified sample */
    645 static snd_sf_sample_t *
    646 set_sample(snd_soundfont_t *sf, soundfont_voice_info_t *avp)
    647 {
    648     snd_sf_sample_t *sample;
    649 
    650     sample = find_sample(sf, avp->sample);
    651     if (sample == NULL)
    652         return NULL;
    653 
    654     /* add in the actual sample offsets:
    655     * The voice_info addresses define only the relative offset
    656     * from sample pointers.  Here we calculate the actual DRAM
    657     * offset from sample pointers.
    658     */
    659     avp->start += sample->v.start;
    660     avp->end += sample->v.end;
    661     avp->loopstart += sample->v.loopstart;
    662     avp->loopend += sample->v.loopend;
    663 
    664     /* copy mode flags */
    665     avp->sample_mode = sample->v.mode_flags;
    666 
    667     return sample;
     655static struct snd_sf_sample *
     656set_sample(struct snd_soundfont *sf, struct soundfont_voice_info *avp)
     657{
     658        struct snd_sf_sample *sample;
     659
     660        sample = find_sample(sf, avp->sample);
     661        if (sample == NULL)
     662                return NULL;
     663
     664        /* add in the actual sample offsets:
     665        * The voice_info addresses define only the relative offset
     666        * from sample pointers.  Here we calculate the actual DRAM
     667        * offset from sample pointers.
     668        */
     669        avp->start += sample->v.start;
     670        avp->end += sample->v.end;
     671        avp->loopstart += sample->v.loopstart;
     672        avp->loopend += sample->v.loopend;
     673
     674        /* copy mode flags */
     675        avp->sample_mode = sample->v.mode_flags;
     676
     677        return sample;
    668678}
    669679
    670680/* find the sample pointer with the given id in the soundfont */
    671 static snd_sf_sample_t *
    672 find_sample(snd_soundfont_t *sf, int sample_id)
    673 {
    674     snd_sf_sample_t *p;
    675 
    676     if (sf == NULL)
    677         return NULL;
    678 
    679     for (p = sf->samples; p; p = p->next) {
    680         if (p->v.sample == sample_id)
    681             return p;
    682     }
    683     return NULL;
     681static struct snd_sf_sample *
     682find_sample(struct snd_soundfont *sf, int sample_id)
     683{
     684        struct snd_sf_sample *p;
     685
     686        if (sf == NULL)
     687                return NULL;
     688
     689        for (p = sf->samples; p; p = p->next) {
     690                if (p->v.sample == sample_id)
     691                        return p;
     692        }
     693        return NULL;
    684694}
    685695
     
    692702 */
    693703static int
    694 load_data(snd_sf_list_t *sflist, const void *data, long count)
    695 {
    696     snd_soundfont_t *sf;
    697     soundfont_sample_info_t sample_info;
    698     snd_sf_sample_t *sp;
    699     long off;
    700 
    701     /* patch must be opened */
    702     if ((sf = sflist->currsf) == NULL)
    703         return -EINVAL;
    704 
    705     if (is_special_type(sf->type))
    706         return -EINVAL;
    707 
    708     if (copy_from_user(&sample_info, data, sizeof(sample_info)))
    709         return -EFAULT;
    710 
    711     off = sizeof(sample_info);
    712 
    713     if (sample_info.size != (count-off)/2)
    714         return -EINVAL;
    715 
    716     /* Check for dup */
    717     if (find_sample(sf, sample_info.sample)) {
    718         /* if shared sample, skip this data */
    719         if (sf->type & SNDRV_SFNT_PAT_SHARED)
    720             return 0;
    721         return -EINVAL;
    722     }
    723 
    724     /* Allocate a new sample structure */
    725     if ((sp = sf_sample_new(sflist, sf)) == NULL)
    726         return -ENOMEM;
    727 
    728     sp->v = sample_info;
    729     sp->v.sf_id = sf->id;
    730     sp->v.dummy = 0;
    731     sp->v.truesize = sp->v.size;
    732 
    733     /*
    734      * If there is wave data then load it.
    735      */
    736     if (sp->v.size > 0) {
    737         int  rc;
    738         rc = sflist->callback.sample_new
    739             (sflist->callback.private_data, sp, sflist->memhdr,
    740 #ifdef TARGET_OS2
    741              (char *)data + off, count - off);
    742 #else
    743         data + off, count - off);
    744 #endif
    745 if (rc < 0) {
    746     sf_sample_delete(sflist, sf, sp);
    747     return rc;
    748 }
    749 sflist->mem_used += sp->v.truesize;
    750 }
    751 
    752 return count;
     704load_data(struct snd_sf_list *sflist, const void __user *data, long count)
     705{
     706        struct snd_soundfont *sf;
     707        struct soundfont_sample_info sample_info;
     708        struct snd_sf_sample *sp;
     709        long off;
     710
     711        /* patch must be opened */
     712        if ((sf = sflist->currsf) == NULL)
     713                return -EINVAL;
     714
     715        if (is_special_type(sf->type))
     716                return -EINVAL;
     717
     718        if (copy_from_user(&sample_info, data, sizeof(sample_info)))
     719                return -EFAULT;
     720
     721        off = sizeof(sample_info);
     722
     723        if (sample_info.size != (count-off)/2)
     724                return -EINVAL;
     725
     726        /* Check for dup */
     727        if (find_sample(sf, sample_info.sample)) {
     728                /* if shared sample, skip this data */
     729                if (sf->type & SNDRV_SFNT_PAT_SHARED)
     730                        return 0;
     731                return -EINVAL;
     732        }
     733
     734        /* Allocate a new sample structure */
     735        if ((sp = sf_sample_new(sflist, sf)) == NULL)
     736                return -ENOMEM;
     737
     738        sp->v = sample_info;
     739        sp->v.sf_id = sf->id;
     740        sp->v.dummy = 0;
     741        sp->v.truesize = sp->v.size;
     742
     743        /*
     744         * If there is wave data then load it.
     745         */
     746        if (sp->v.size > 0) {
     747                int  rc;
     748                rc = sflist->callback.sample_new
     749                        (sflist->callback.private_data, sp, sflist->memhdr,
     750                         (char*)data + off, count - off);
     751                if (rc < 0) {
     752                        sf_sample_delete(sflist, sf, sp);
     753                        return rc;
     754                }
     755                sflist->mem_used += sp->v.truesize;
     756        }
     757
     758        return count;
    753759}
    754760
     
    756762/* log2_tbl[i] = log2(i+128) * 0x10000 */
    757763static int log_tbl[129] = {
    758     0x70000, 0x702df, 0x705b9, 0x7088e, 0x70b5d, 0x70e26, 0x710eb, 0x713aa,
    759     0x71663, 0x71918, 0x71bc8, 0x71e72, 0x72118, 0x723b9, 0x72655, 0x728ed,
    760     0x72b80, 0x72e0e, 0x73098, 0x7331d, 0x7359e, 0x7381b, 0x73a93, 0x73d08,
    761     0x73f78, 0x741e4, 0x7444c, 0x746b0, 0x74910, 0x74b6c, 0x74dc4, 0x75019,
    762     0x75269, 0x754b6, 0x75700, 0x75946, 0x75b88, 0x75dc7, 0x76002, 0x7623a,
    763     0x7646e, 0x766a0, 0x768cd, 0x76af8, 0x76d1f, 0x76f43, 0x77164, 0x77382,
    764     0x7759d, 0x777b4, 0x779c9, 0x77bdb, 0x77dea, 0x77ff5, 0x781fe, 0x78404,
    765     0x78608, 0x78808, 0x78a06, 0x78c01, 0x78df9, 0x78fef, 0x791e2, 0x793d2,
    766     0x795c0, 0x797ab, 0x79993, 0x79b79, 0x79d5d, 0x79f3e, 0x7a11d, 0x7a2f9,
    767     0x7a4d3, 0x7a6ab, 0x7a880, 0x7aa53, 0x7ac24, 0x7adf2, 0x7afbe, 0x7b188,
    768     0x7b350, 0x7b515, 0x7b6d8, 0x7b899, 0x7ba58, 0x7bc15, 0x7bdd0, 0x7bf89,
    769     0x7c140, 0x7c2f5, 0x7c4a7, 0x7c658, 0x7c807, 0x7c9b3, 0x7cb5e, 0x7cd07,
    770     0x7ceae, 0x7d053, 0x7d1f7, 0x7d398, 0x7d538, 0x7d6d6, 0x7d872, 0x7da0c,
    771     0x7dba4, 0x7dd3b, 0x7ded0, 0x7e063, 0x7e1f4, 0x7e384, 0x7e512, 0x7e69f,
    772     0x7e829, 0x7e9b3, 0x7eb3a, 0x7ecc0, 0x7ee44, 0x7efc7, 0x7f148, 0x7f2c8,
    773     0x7f446, 0x7f5c2, 0x7f73d, 0x7f8b7, 0x7fa2f, 0x7fba5, 0x7fd1a, 0x7fe8d,
    774     0x80000,
     764        0x70000, 0x702df, 0x705b9, 0x7088e, 0x70b5d, 0x70e26, 0x710eb, 0x713aa,
     765        0x71663, 0x71918, 0x71bc8, 0x71e72, 0x72118, 0x723b9, 0x72655, 0x728ed,
     766        0x72b80, 0x72e0e, 0x73098, 0x7331d, 0x7359e, 0x7381b, 0x73a93, 0x73d08,
     767        0x73f78, 0x741e4, 0x7444c, 0x746b0, 0x74910, 0x74b6c, 0x74dc4, 0x75019,
     768        0x75269, 0x754b6, 0x75700, 0x75946, 0x75b88, 0x75dc7, 0x76002, 0x7623a,
     769        0x7646e, 0x766a0, 0x768cd, 0x76af8, 0x76d1f, 0x76f43, 0x77164, 0x77382,
     770        0x7759d, 0x777b4, 0x779c9, 0x77bdb, 0x77dea, 0x77ff5, 0x781fe, 0x78404,
     771        0x78608, 0x78808, 0x78a06, 0x78c01, 0x78df9, 0x78fef, 0x791e2, 0x793d2,
     772        0x795c0, 0x797ab, 0x79993, 0x79b79, 0x79d5d, 0x79f3e, 0x7a11d, 0x7a2f9,
     773        0x7a4d3, 0x7a6ab, 0x7a880, 0x7aa53, 0x7ac24, 0x7adf2, 0x7afbe, 0x7b188,
     774        0x7b350, 0x7b515, 0x7b6d8, 0x7b899, 0x7ba58, 0x7bc15, 0x7bdd0, 0x7bf89,
     775        0x7c140, 0x7c2f5, 0x7c4a7, 0x7c658, 0x7c807, 0x7c9b3, 0x7cb5e, 0x7cd07,
     776        0x7ceae, 0x7d053, 0x7d1f7, 0x7d398, 0x7d538, 0x7d6d6, 0x7d872, 0x7da0c,
     777        0x7dba4, 0x7dd3b, 0x7ded0, 0x7e063, 0x7e1f4, 0x7e384, 0x7e512, 0x7e69f,
     778        0x7e829, 0x7e9b3, 0x7eb3a, 0x7ecc0, 0x7ee44, 0x7efc7, 0x7f148, 0x7f2c8,
     779        0x7f446, 0x7f5c2, 0x7f73d, 0x7f8b7, 0x7fa2f, 0x7fba5, 0x7fd1a, 0x7fe8d,
     780        0x80000,
    775781};
    776782
     
    788794snd_sf_linear_to_log(unsigned int amount, int offset, int ratio)
    789795{
    790     int v;
    791     int s, low, bit;
    792 
    793     if (amount < 2)
    794         return 0;
    795     for (bit = 0; ! (amount & 0x80000000L); bit++)
    796         amount <<= 1;
    797     s = (amount >> 24) & 0x7f;
    798     low = (amount >> 16) & 0xff;
    799     /* linear approxmimation by lower 8 bit */
    800     v = (log_tbl[s + 1] * low + log_tbl[s] * (0x100 - low)) >> 8;
    801     v -= offset;
    802     v = (v * ratio) >> 16;
    803     v += (24 - bit) * ratio;
    804     return v;
     796        int v;
     797        int s, low, bit;
     798       
     799        if (amount < 2)
     800                return 0;
     801        for (bit = 0; ! (amount & 0x80000000L); bit++)
     802                amount <<= 1;
     803        s = (amount >> 24) & 0x7f;
     804        low = (amount >> 16) & 0xff;
     805        /* linear approxmimation by lower 8 bit */
     806        v = (log_tbl[s + 1] * low + log_tbl[s] * (0x100 - low)) >> 8;
     807        v -= offset;
     808        v = (v * ratio) >> 16;
     809        v += (24 - bit) * ratio;
     810        return v;
    805811}
    806812
     
    820826freq_to_note(int mhz)
    821827{
    822     return snd_sf_linear_to_log(mhz, OFFSET_ABSCENT, ABSCENT_RATIO);
     828        return snd_sf_linear_to_log(mhz, OFFSET_ABSCENT, ABSCENT_RATIO);
    823829}
    824830
     
    833839calc_rate_offset(int hz)
    834840{
    835     return snd_sf_linear_to_log(hz, OFFSET_SAMPLERATE, SAMPLERATE_RATIO);
     841        return snd_sf_linear_to_log(hz, OFFSET_SAMPLERATE, SAMPLERATE_RATIO);
    836842}
    837843
     
    841847calc_gus_envelope_time(int rate, int start, int end)
    842848{
    843     int r, p, t;
    844     r = (3 - ((rate >> 6) & 3)) * 3;
    845     p = rate & 0x3f;
    846     t = end - start;
    847     if (t < 0) t = -t;
    848     if (13 > r)
    849         t = t << (13 - r);
    850     else
    851         t = t >> (r - 13);
    852     return (t * 10) / (p * 441);
     849        int r, p, t;
     850        r = (3 - ((rate >> 6) & 3)) * 3;
     851        p = rate & 0x3f;
     852        t = end - start;
     853        if (t < 0) t = -t;
     854        if (13 > r)
     855                t = t << (13 - r);
     856        else
     857                t = t >> (r - 13);
     858        return (t * 10) / (p * 441);
    853859}
    854860
     
    857863/* attack & decay/release time table (msec) */
    858864static short attack_time_tbl[128] = {
    859     32767, 32767, 5989, 4235, 2994, 2518, 2117, 1780, 1497, 1373, 1259, 1154, 1058, 970, 890, 816,
    860     707, 691, 662, 634, 607, 581, 557, 533, 510, 489, 468, 448, 429, 411, 393, 377,
    861     361, 345, 331, 317, 303, 290, 278, 266, 255, 244, 234, 224, 214, 205, 196, 188,
    862     180, 172, 165, 158, 151, 145, 139, 133, 127, 122, 117, 112, 107, 102, 98, 94,
    863     90, 86, 82, 79, 75, 72, 69, 66, 63, 61, 58, 56, 53, 51, 49, 47,
    864     45, 43, 41, 39, 37, 36, 34, 33, 31, 30, 29, 28, 26, 25, 24, 23,
    865     22, 21, 20, 19, 19, 18, 17, 16, 16, 15, 15, 14, 13, 13, 12, 12,
    866     11, 11, 10, 10, 10, 9, 9, 8, 8, 8, 8, 7, 7, 7, 6, 0,
     86532767, 32767, 5989, 4235, 2994, 2518, 2117, 1780, 1497, 1373, 1259, 1154, 1058, 970, 890, 816,
     866707, 691, 662, 634, 607, 581, 557, 533, 510, 489, 468, 448, 429, 411, 393, 377,
     867361, 345, 331, 317, 303, 290, 278, 266, 255, 244, 234, 224, 214, 205, 196, 188,
     868180, 172, 165, 158, 151, 145, 139, 133, 127, 122, 117, 112, 107, 102, 98, 94,
     86990, 86, 82, 79, 75, 72, 69, 66, 63, 61, 58, 56, 53, 51, 49, 47,
     87045, 43, 41, 39, 37, 36, 34, 33, 31, 30, 29, 28, 26, 25, 24, 23,
     87122, 21, 20, 19, 19, 18, 17, 16, 16, 15, 15, 14, 13, 13, 12, 12,
     87211, 11, 10, 10, 10, 9, 9, 8, 8, 8, 8, 7, 7, 7, 6, 0,
    867873};
    868874
    869875static short decay_time_tbl[128] = {
    870     32767, 32767, 22614, 15990, 11307, 9508, 7995, 6723, 5653, 5184, 4754, 4359, 3997, 3665, 3361, 3082,
    871     2828, 2765, 2648, 2535, 2428, 2325, 2226, 2132, 2042, 1955, 1872, 1793, 1717, 1644, 1574, 1507,
    872     1443, 1382, 1324, 1267, 1214, 1162, 1113, 1066, 978, 936, 897, 859, 822, 787, 754, 722,
    873     691, 662, 634, 607, 581, 557, 533, 510, 489, 468, 448, 429, 411, 393, 377, 361,
    874     345, 331, 317, 303, 290, 278, 266, 255, 244, 234, 224, 214, 205, 196, 188, 180,
    875     172, 165, 158, 151, 145, 139, 133, 127, 122, 117, 112, 107, 102, 98, 94, 90,
    876     86, 82, 79, 75, 72, 69, 66, 63, 61, 58, 56, 53, 51, 49, 47, 45,
    877     43, 41, 39, 37, 36, 34, 33, 31, 30, 29, 28, 26, 25, 24, 23, 22,
     87632767, 32767, 22614, 15990, 11307, 9508, 7995, 6723, 5653, 5184, 4754, 4359, 3997, 3665, 3361, 3082,
     8772828, 2765, 2648, 2535, 2428, 2325, 2226, 2132, 2042, 1955, 1872, 1793, 1717, 1644, 1574, 1507,
     8781443, 1382, 1324, 1267, 1214, 1162, 1113, 1066, 978, 936, 897, 859, 822, 787, 754, 722,
     879691, 662, 634, 607, 581, 557, 533, 510, 489, 468, 448, 429, 411, 393, 377, 361,
     880345, 331, 317, 303, 290, 278, 266, 255, 244, 234, 224, 214, 205, 196, 188, 180,
     881172, 165, 158, 151, 145, 139, 133, 127, 122, 117, 112, 107, 102, 98, 94, 90,
     88286, 82, 79, 75, 72, 69, 66, 63, 61, 58, 56, 53, 51, 49, 47, 45,
     88343, 41, 39, 37, 36, 34, 33, 31, 30, 29, 28, 26, 25, 24, 23, 22,
    878884};
    879885
     
    882888snd_sf_calc_parm_hold(int msec)
    883889{
    884     int val = (0x7f * 92 - msec) / 92;
    885     if (val < 1) val = 1;
    886     if (val >= 126) val = 126;
    887     return val;
     890        int val = (0x7f * 92 - msec) / 92;
     891        if (val < 1) val = 1;
     892        if (val >= 126) val = 126;
     893        return val;
    888894}
    889895
     
    892898calc_parm_search(int msec, short *table)
    893899{
    894     int left = 1, right = 127, mid;
    895     while (left < right) {
    896         mid = (left + right) / 2;
    897         if (msec < (int)table[mid])
    898             left = mid + 1;
    899         else
    900             right = mid;
    901     }
    902     return left;
     900        int left = 1, right = 127, mid;
     901        while (left < right) {
     902                mid = (left + right) / 2;
     903                if (msec < (int)table[mid])
     904                        left = mid + 1;
     905                else
     906                        right = mid;
     907        }
     908        return left;
    903909}
    904910
     
    907913snd_sf_calc_parm_attack(int msec)
    908914{
    909     return calc_parm_search(msec, attack_time_tbl);
     915        return calc_parm_search(msec, attack_time_tbl);
    910916}
    911917
     
    914920snd_sf_calc_parm_decay(int msec)
    915921{
    916     return calc_parm_search(msec, decay_time_tbl);
     922        return calc_parm_search(msec, decay_time_tbl);
    917923}
    918924
    919925int snd_sf_vol_table[128] = {
    920     255,111,95,86,79,74,70,66,63,61,58,56,54,52,50,49,
    921     47,46,45,43,42,41,40,39,38,37,36,35,34,34,33,32,
    922     31,31,30,29,29,28,27,27,26,26,25,24,24,23,23,22,
    923     22,21,21,21,20,20,19,19,18,18,18,17,17,16,16,16,
    924     15,15,15,14,14,14,13,13,13,12,12,12,11,11,11,10,
    925     10,10,10,9,9,9,8,8,8,8,7,7,7,7,6,6,
    926     6,6,5,5,5,5,5,4,4,4,4,3,3,3,3,3,
    927     2,2,2,2,2,1,1,1,1,1,0,0,0,0,0,0,
     926        255,111,95,86,79,74,70,66,63,61,58,56,54,52,50,49,
     927        47,46,45,43,42,41,40,39,38,37,36,35,34,34,33,32,
     928        31,31,30,29,29,28,27,27,26,26,25,24,24,23,23,22,
     929        22,21,21,21,20,20,19,19,18,18,18,17,17,16,16,16,
     930        15,15,15,14,14,14,13,13,13,12,12,12,11,11,11,10,
     931        10,10,10,9,9,9,8,8,8,8,7,7,7,7,6,6,
     932        6,6,5,5,5,5,5,4,4,4,4,3,3,3,3,3,
     933        2,2,2,2,2,1,1,1,1,1,0,0,0,0,0,0,
    928934};
    929935
     
    934940/* load GUS patch */
    935941static int
    936 load_guspatch(snd_sf_list_t *sflist, const char *data, long count, int client)
    937 {
    938     struct patch_info patch;
    939     snd_soundfont_t *sf;
    940     snd_sf_zone_t *zone;
    941     snd_sf_sample_t *smp;
    942     int note, sample_id;
    943     int rc;
    944 
    945     if (count < sizeof(patch)) {
    946         snd_printk("patch record too small %ld\n", count);
    947         return -EINVAL;
    948     }
    949     if (copy_from_user(&patch, data, sizeof(patch)))
    950         return -EFAULT;
    951 
    952     count -= sizeof(patch);
    953     data += sizeof(patch);
    954 
    955     sf = newsf(sflist, SNDRV_SFNT_PAT_TYPE_GUS|SNDRV_SFNT_PAT_SHARED, NULL);
    956     if (sf == NULL)
    957         return -ENOMEM;
    958     if ((smp = sf_sample_new(sflist, sf)) == NULL)
    959         return -ENOMEM;
    960     sample_id = sflist->sample_counter;
    961     smp->v.sample = sample_id;
    962     smp->v.start = 0;
    963     smp->v.end = patch.len;
    964     smp->v.loopstart = patch.loop_start;
    965     smp->v.loopend = patch.loop_end;
    966     smp->v.size = patch.len;
    967 
    968     /* set up mode flags */
    969     smp->v.mode_flags = 0;
    970     if (!(patch.mode & WAVE_16_BITS))
    971         smp->v.mode_flags |= SNDRV_SFNT_SAMPLE_8BITS;
    972     if (patch.mode & WAVE_UNSIGNED)
    973         smp->v.mode_flags |= SNDRV_SFNT_SAMPLE_UNSIGNED;
    974     smp->v.mode_flags |= SNDRV_SFNT_SAMPLE_NO_BLANK;
    975     if (!(patch.mode & (WAVE_LOOPING|WAVE_BIDIR_LOOP|WAVE_LOOP_BACK)))
    976         smp->v.mode_flags |= SNDRV_SFNT_SAMPLE_SINGLESHOT;
    977     if (patch.mode & WAVE_BIDIR_LOOP)
    978         smp->v.mode_flags |= SNDRV_SFNT_SAMPLE_BIDIR_LOOP;
    979     if (patch.mode & WAVE_LOOP_BACK)
    980         smp->v.mode_flags |= SNDRV_SFNT_SAMPLE_REVERSE_LOOP;
    981 
    982     if (patch.mode & WAVE_16_BITS) {
    983         /* convert to word offsets */
    984         smp->v.size /= 2;
    985         smp->v.end /= 2;
    986         smp->v.loopstart /= 2;
    987         smp->v.loopend /= 2;
    988     }
    989     /*smp->v.loopend++;*/
    990 
    991     smp->v.dummy = 0;
    992     smp->v.truesize = 0;
    993     smp->v.sf_id = sf->id;
    994 
    995     /* set up voice info */
    996     if ((zone = sf_zone_new(sflist, sf)) == NULL) {
    997         sf_sample_delete(sflist, sf, smp);
    998         return -ENOMEM;
    999     }
    1000 
    1001     /*
    1002      * load wave data
    1003      */
    1004     if (sflist->callback.sample_new) {
    1005         rc = sflist->callback.sample_new
    1006             (sflist->callback.private_data, smp, sflist->memhdr, data, count);
    1007         if (rc < 0) {
    1008             sf_sample_delete(sflist, sf, smp);
    1009             return rc;
    1010         }
    1011         /* memory offset is updated after */
    1012     }
    1013 
    1014     /* update the memory offset here */
    1015     sflist->mem_used += smp->v.truesize;
    1016 
    1017     zone->v.sample = sample_id; /* the last sample */
    1018     zone->v.rate_offset = calc_rate_offset(patch.base_freq);
    1019     note = freq_to_note(patch.base_note);
    1020     zone->v.root = note / 100;
    1021     zone->v.tune = -(note % 100);
    1022     zone->v.low = (freq_to_note(patch.low_note) + 99) / 100;
    1023     zone->v.high = freq_to_note(patch.high_note) / 100;
    1024     /* panning position; -128 - 127 => 0-127 */
    1025     zone->v.pan = (patch.panning + 128) / 2;
     942load_guspatch(struct snd_sf_list *sflist, const char __user *data,
     943              long count, int client)
     944{
     945        struct patch_info patch;
     946        struct snd_soundfont *sf;
     947        struct snd_sf_zone *zone;
     948        struct snd_sf_sample *smp;
     949        int note, sample_id;
     950        int rc;
     951
     952        if (count < (long)sizeof(patch)) {
     953                snd_printk("patch record too small %ld\n", count);
     954                return -EINVAL;
     955        }
     956        if (copy_from_user(&patch, data, sizeof(patch)))
     957                return -EFAULT;
     958       
     959        count -= sizeof(patch);
     960        data += sizeof(patch);
     961
     962        sf = newsf(sflist, SNDRV_SFNT_PAT_TYPE_GUS|SNDRV_SFNT_PAT_SHARED, NULL);
     963        if (sf == NULL)
     964                return -ENOMEM;
     965        if ((smp = sf_sample_new(sflist, sf)) == NULL)
     966                return -ENOMEM;
     967        sample_id = sflist->sample_counter;
     968        smp->v.sample = sample_id;
     969        smp->v.start = 0;
     970        smp->v.end = patch.len;
     971        smp->v.loopstart = patch.loop_start;
     972        smp->v.loopend = patch.loop_end;
     973        smp->v.size = patch.len;
     974
     975        /* set up mode flags */
     976        smp->v.mode_flags = 0;
     977        if (!(patch.mode & WAVE_16_BITS))
     978                smp->v.mode_flags |= SNDRV_SFNT_SAMPLE_8BITS;
     979        if (patch.mode & WAVE_UNSIGNED)
     980                smp->v.mode_flags |= SNDRV_SFNT_SAMPLE_UNSIGNED;
     981        smp->v.mode_flags |= SNDRV_SFNT_SAMPLE_NO_BLANK;
     982        if (!(patch.mode & (WAVE_LOOPING|WAVE_BIDIR_LOOP|WAVE_LOOP_BACK)))
     983                smp->v.mode_flags |= SNDRV_SFNT_SAMPLE_SINGLESHOT;
     984        if (patch.mode & WAVE_BIDIR_LOOP)
     985                smp->v.mode_flags |= SNDRV_SFNT_SAMPLE_BIDIR_LOOP;
     986        if (patch.mode & WAVE_LOOP_BACK)
     987                smp->v.mode_flags |= SNDRV_SFNT_SAMPLE_REVERSE_LOOP;
     988
     989        if (patch.mode & WAVE_16_BITS) {
     990                /* convert to word offsets */
     991                smp->v.size /= 2;
     992                smp->v.end /= 2;
     993                smp->v.loopstart /= 2;
     994                smp->v.loopend /= 2;
     995        }
     996        /*smp->v.loopend++;*/
     997
     998        smp->v.dummy = 0;
     999        smp->v.truesize = 0;
     1000        smp->v.sf_id = sf->id;
     1001
     1002        /* set up voice info */
     1003        if ((zone = sf_zone_new(sflist, sf)) == NULL) {
     1004                sf_sample_delete(sflist, sf, smp);
     1005                return -ENOMEM;
     1006        }
     1007
     1008        /*
     1009         * load wave data
     1010         */
     1011        if (sflist->callback.sample_new) {
     1012                rc = sflist->callback.sample_new
     1013                        (sflist->callback.private_data, smp, sflist->memhdr,
     1014                         data, count);
     1015                if (rc < 0) {
     1016                        sf_sample_delete(sflist, sf, smp);
     1017                        return rc;
     1018                }
     1019                /* memory offset is updated after */
     1020        }
     1021
     1022        /* update the memory offset here */
     1023        sflist->mem_used += smp->v.truesize;
     1024
     1025        zone->v.sample = sample_id; /* the last sample */
     1026        zone->v.rate_offset = calc_rate_offset(patch.base_freq);
     1027        note = freq_to_note(patch.base_note);
     1028        zone->v.root = note / 100;
     1029        zone->v.tune = -(note % 100);
     1030        zone->v.low = (freq_to_note(patch.low_note) + 99) / 100;
     1031        zone->v.high = freq_to_note(patch.high_note) / 100;
     1032        /* panning position; -128 - 127 => 0-127 */
     1033        zone->v.pan = (patch.panning + 128) / 2;
    10261034#if 0
    1027     snd_printk("gus: basefrq=%d (ofs=%d) root=%d,tune=%d, range:%d-%d\n",
    1028                (int)patch.base_freq, zone->v.rate_offset,
    1029                zone->v.root, zone->v.tune, zone->v.low, zone->v.high);
     1035        snd_printk("gus: basefrq=%d (ofs=%d) root=%d,tune=%d, range:%d-%d\n",
     1036                   (int)patch.base_freq, zone->v.rate_offset,
     1037                   zone->v.root, zone->v.tune, zone->v.low, zone->v.high);
    10301038#endif
    10311039
    1032     /* detuning is ignored */
    1033     /* 6points volume envelope */
    1034     if (patch.mode & WAVE_ENVELOPES) {
    1035         int attack, hold, decay, release;
    1036         attack = calc_gus_envelope_time
    1037             (patch.env_rate[0], 0, patch.env_offset[0]);
    1038         hold = calc_gus_envelope_time
    1039             (patch.env_rate[1], patch.env_offset[0],
    1040             patch.env_offset[1]);
    1041         decay = calc_gus_envelope_time
    1042             (patch.env_rate[2], patch.env_offset[1],
    1043             patch.env_offset[2]);
    1044         release = calc_gus_envelope_time
    1045             (patch.env_rate[3], patch.env_offset[1],
    1046             patch.env_offset[4]);
    1047         release += calc_gus_envelope_time
    1048             (patch.env_rate[4], patch.env_offset[3],
    1049             patch.env_offset[4]);
    1050         release += calc_gus_envelope_time
    1051             (patch.env_rate[5], patch.env_offset[4],
    1052             patch.env_offset[5]);
    1053         zone->v.parm.volatkhld =
    1054             (snd_sf_calc_parm_hold(hold) << 8) |
    1055             snd_sf_calc_parm_attack(attack);
    1056         zone->v.parm.voldcysus = (calc_gus_sustain(patch.env_offset[2]) << 8) |
    1057             snd_sf_calc_parm_decay(decay);
    1058         zone->v.parm.volrelease = 0x8000 | snd_sf_calc_parm_decay(release);
    1059         zone->v.attenuation = calc_gus_attenuation(patch.env_offset[0]);
     1040        /* detuning is ignored */
     1041        /* 6points volume envelope */
     1042        if (patch.mode & WAVE_ENVELOPES) {
     1043                int attack, hold, decay, release;
     1044                attack = calc_gus_envelope_time
     1045                        (patch.env_rate[0], 0, patch.env_offset[0]);
     1046                hold = calc_gus_envelope_time
     1047                        (patch.env_rate[1], patch.env_offset[0],
     1048                        patch.env_offset[1]);
     1049                decay = calc_gus_envelope_time
     1050                        (patch.env_rate[2], patch.env_offset[1],
     1051                        patch.env_offset[2]);
     1052                release = calc_gus_envelope_time
     1053                        (patch.env_rate[3], patch.env_offset[1],
     1054                        patch.env_offset[4]);
     1055                release += calc_gus_envelope_time
     1056                        (patch.env_rate[4], patch.env_offset[3],
     1057                        patch.env_offset[4]);
     1058                release += calc_gus_envelope_time
     1059                        (patch.env_rate[5], patch.env_offset[4],
     1060                        patch.env_offset[5]);
     1061                zone->v.parm.volatkhld =
     1062                        (snd_sf_calc_parm_hold(hold) << 8) |
     1063                        snd_sf_calc_parm_attack(attack);
     1064                zone->v.parm.voldcysus = (calc_gus_sustain(patch.env_offset[2]) << 8) |
     1065                        snd_sf_calc_parm_decay(decay);
     1066                zone->v.parm.volrelease = 0x8000 | snd_sf_calc_parm_decay(release);
     1067                zone->v.attenuation = calc_gus_attenuation(patch.env_offset[0]);
    10601068#if 0
    1061         snd_printk("gus: atkhld=%x, dcysus=%x, volrel=%x, att=%d\n",
    1062                    zone->v.parm.volatkhld,
    1063                    zone->v.parm.voldcysus,
    1064                    zone->v.parm.volrelease,
    1065                    zone->v.attenuation);
     1069                snd_printk("gus: atkhld=%x, dcysus=%x, volrel=%x, att=%d\n",
     1070                           zone->v.parm.volatkhld,
     1071                           zone->v.parm.voldcysus,
     1072                           zone->v.parm.volrelease,
     1073                           zone->v.attenuation);
    10661074#endif
    1067     }
    1068 
    1069     /* fast release */
    1070     if (patch.mode & WAVE_FAST_RELEASE) {
    1071         zone->v.parm.volrelease = 0x807f;
    1072     }
    1073 
    1074     /* tremolo effect */
    1075     if (patch.mode & WAVE_TREMOLO) {
    1076         int rate = (patch.tremolo_rate * 1000 / 38) / 42;
    1077         zone->v.parm.tremfrq = ((patch.tremolo_depth / 2) << 8) | rate;
    1078     }
    1079     /* vibrato effect */
    1080     if (patch.mode & WAVE_VIBRATO) {
    1081         int rate = (patch.vibrato_rate * 1000 / 38) / 42;
    1082         zone->v.parm.fm2frq2 = ((patch.vibrato_depth / 6) << 8) | rate;
    1083     }
    1084 
    1085     /* scale_freq, scale_factor, volume, and fractions not implemented */
    1086 
    1087     if (!(smp->v.mode_flags & SNDRV_SFNT_SAMPLE_SINGLESHOT))
    1088         zone->v.mode = SNDRV_SFNT_MODE_LOOPING;
    1089     else
    1090         zone->v.mode = 0;
    1091 
    1092     /* append to the tail of the list */
    1093     /*zone->bank = ctrls[AWE_MD_GUS_BANK];*/
    1094     zone->bank = 0;
    1095     zone->instr = patch.instr_no;
    1096     zone->mapped = 0;
    1097     zone->v.sf_id = sf->id;
    1098 
    1099     zone->sample = set_sample(sf, &zone->v);
    1100 
    1101     /* rebuild preset now */
    1102     add_preset(sflist, zone);
    1103 
    1104     return 0;
     1075        }
     1076
     1077        /* fast release */
     1078        if (patch.mode & WAVE_FAST_RELEASE) {
     1079                zone->v.parm.volrelease = 0x807f;
     1080        }
     1081
     1082        /* tremolo effect */
     1083        if (patch.mode & WAVE_TREMOLO) {
     1084                int rate = (patch.tremolo_rate * 1000 / 38) / 42;
     1085                zone->v.parm.tremfrq = ((patch.tremolo_depth / 2) << 8) | rate;
     1086        }
     1087        /* vibrato effect */
     1088        if (patch.mode & WAVE_VIBRATO) {
     1089                int rate = (patch.vibrato_rate * 1000 / 38) / 42;
     1090                zone->v.parm.fm2frq2 = ((patch.vibrato_depth / 6) << 8) | rate;
     1091        }
     1092       
     1093        /* scale_freq, scale_factor, volume, and fractions not implemented */
     1094
     1095        if (!(smp->v.mode_flags & SNDRV_SFNT_SAMPLE_SINGLESHOT))
     1096                zone->v.mode = SNDRV_SFNT_MODE_LOOPING;
     1097        else
     1098                zone->v.mode = 0;
     1099
     1100        /* append to the tail of the list */
     1101        /*zone->bank = ctrls[AWE_MD_GUS_BANK];*/
     1102        zone->bank = 0;
     1103        zone->instr = patch.instr_no;
     1104        zone->mapped = 0;
     1105        zone->v.sf_id = sf->id;
     1106
     1107        zone->sample = set_sample(sf, &zone->v);
     1108
     1109        /* rebuild preset now */
     1110        add_preset(sflist, zone);
     1111
     1112        return 0;
    11051113}
    11061114
    11071115/* load GUS patch */
    11081116int
    1109 snd_soundfont_load_guspatch(snd_sf_list_t *sflist, const char *data,
    1110                             long count, int client)
    1111 {
    1112     int rc;
    1113     lock_preset(sflist, 0);
    1114     rc = load_guspatch(sflist, data, count, client);
    1115     unlock_preset(sflist);
    1116     return rc;
     1117snd_soundfont_load_guspatch(struct snd_sf_list *sflist, const char __user *data,
     1118                            long count, int client)
     1119{
     1120        int rc;
     1121        lock_preset(sflist);
     1122        rc = load_guspatch(sflist, data, count, client);
     1123        unlock_preset(sflist);
     1124        return rc;
    11171125}
    11181126
     
    11261134 */
    11271135static void
    1128 rebuild_presets(snd_sf_list_t *sflist)
    1129 {
    1130     snd_soundfont_t *sf;
    1131     snd_sf_zone_t *cur;
    1132 
    1133     /* clear preset table */
    1134     memset(sflist->presets, 0, sizeof(sflist->presets));
    1135 
    1136     /* search all fonts and insert each font */
    1137     for (sf = sflist->fonts; sf; sf = sf->next) {
    1138         for (cur = sf->zones; cur; cur = cur->next) {
    1139             if (! cur->mapped && cur->sample == NULL) {
    1140                 /* try again to search the corresponding sample */
    1141                 cur->sample = set_sample(sf, &cur->v);
    1142                 if (cur->sample == NULL)
    1143                     continue;
    1144             }
    1145 
    1146             add_preset(sflist, cur);
    1147         }
    1148     }
     1136rebuild_presets(struct snd_sf_list *sflist)
     1137{
     1138        struct snd_soundfont *sf;
     1139        struct snd_sf_zone *cur;
     1140
     1141        /* clear preset table */
     1142        memset(sflist->presets, 0, sizeof(sflist->presets));
     1143
     1144        /* search all fonts and insert each font */
     1145        for (sf = sflist->fonts; sf; sf = sf->next) {
     1146                for (cur = sf->zones; cur; cur = cur->next) {
     1147                        if (! cur->mapped && cur->sample == NULL) {
     1148                                /* try again to search the corresponding sample */
     1149                                cur->sample = set_sample(sf, &cur->v);
     1150                                if (cur->sample == NULL)
     1151                                        continue;
     1152                        }
     1153
     1154                        add_preset(sflist, cur);
     1155                }
     1156        }
    11491157}
    11501158
     
    11541162 */
    11551163static void
    1156 add_preset(snd_sf_list_t *sflist, snd_sf_zone_t *cur)
    1157 {
    1158     snd_sf_zone_t *zone;
    1159     int index;
    1160 
    1161     zone = search_first_zone(sflist, cur->bank, cur->instr, cur->v.low);
    1162     if (zone && zone->v.sf_id != cur->v.sf_id) {
    1163         /* different instrument was already defined */
    1164         snd_sf_zone_t *p;
    1165         /* compare the allocated time */
    1166         for (p = zone; p; p = p->next_zone) {
    1167             if (p->counter > cur->counter)
    1168                 /* the current is older.. skipped */
    1169                 return;
    1170         }
    1171         /* remove old zones */
    1172         delete_preset(sflist, zone);
    1173         zone = NULL; /* do not forget to clear this! */
    1174     }
    1175 
    1176     /* prepend this zone */
    1177     if ((index = get_index(cur->bank, cur->instr, cur->v.low)) < 0)
    1178         return;
    1179     cur->next_zone = zone; /* zone link */
    1180     cur->next_instr = sflist->presets[index]; /* preset table link */
    1181     sflist->presets[index] = cur;
     1164add_preset(struct snd_sf_list *sflist, struct snd_sf_zone *cur)
     1165{
     1166        struct snd_sf_zone *zone;
     1167        int index;
     1168
     1169        zone = search_first_zone(sflist, cur->bank, cur->instr, cur->v.low);
     1170        if (zone && zone->v.sf_id != cur->v.sf_id) {
     1171                /* different instrument was already defined */
     1172                struct snd_sf_zone *p;
     1173                /* compare the allocated time */
     1174                for (p = zone; p; p = p->next_zone) {
     1175                        if (p->counter > cur->counter)
     1176                                /* the current is older.. skipped */
     1177                                return;
     1178                }
     1179                /* remove old zones */
     1180                delete_preset(sflist, zone);
     1181                zone = NULL; /* do not forget to clear this! */
     1182        }
     1183
     1184        /* prepend this zone */
     1185        if ((index = get_index(cur->bank, cur->instr, cur->v.low)) < 0)
     1186                return;
     1187        cur->next_zone = zone; /* zone link */
     1188        cur->next_instr = sflist->presets[index]; /* preset table link */
     1189        sflist->presets[index] = cur;
    11821190}
    11831191
     
    11861194 */
    11871195static void
    1188 delete_preset(snd_sf_list_t *sflist, snd_sf_zone_t *zp)
    1189 {
    1190     int index;
    1191     snd_sf_zone_t *p;
    1192 
    1193     if ((index = get_index(zp->bank, zp->instr, zp->v.low)) < 0)
    1194         return;
    1195     for (p = sflist->presets[index]; p; p = p->next_instr) {
    1196         while (p->next_instr == zp) {
    1197             p->next_instr = zp->next_instr;
    1198             zp = zp->next_zone;
    1199             if (zp == NULL)
    1200                 return;
    1201         }
    1202     }
     1196delete_preset(struct snd_sf_list *sflist, struct snd_sf_zone *zp)
     1197{
     1198        int index;
     1199        struct snd_sf_zone *p;
     1200
     1201        if ((index = get_index(zp->bank, zp->instr, zp->v.low)) < 0)
     1202                return;
     1203        for (p = sflist->presets[index]; p; p = p->next_instr) {
     1204                while (p->next_instr == zp) {
     1205                        p->next_instr = zp->next_instr;
     1206                        zp = zp->next_zone;
     1207                        if (zp == NULL)
     1208                                return;
     1209                }
     1210        }
    12031211}
    12041212
     
    12121220 */
    12131221int
    1214 snd_soundfont_search_zone(snd_sf_list_t *sflist, int *notep, int vel,
    1215                           int preset, int bank,
    1216                           int def_preset, int def_bank,
    1217                           snd_sf_zone_t **table, int max_layers)
    1218 {
    1219     int nvoices;
    1220 
    1221     if (lock_preset(sflist, 1))
    1222         return 0;
    1223 
    1224     nvoices = search_zones(sflist, notep, vel, preset, bank, table, max_layers, 0);
    1225     if (! nvoices) {
    1226         if (preset != def_preset || bank != def_bank)
    1227             nvoices = search_zones(sflist, notep, vel, def_preset, def_bank, table, max_layers, 0);
    1228     }
    1229     unlock_preset(sflist);
    1230 
    1231     return nvoices;
     1222snd_soundfont_search_zone(struct snd_sf_list *sflist, int *notep, int vel,
     1223                          int preset, int bank,
     1224                          int def_preset, int def_bank,
     1225                          struct snd_sf_zone **table, int max_layers)
     1226{
     1227        int nvoices;
     1228        unsigned long flags;
     1229
     1230        /* this function is supposed to be called atomically,
     1231         * so we check the lock.  if it's busy, just returns 0 to
     1232         * tell the caller the busy state
     1233         */
     1234        spin_lock_irqsave(&sflist->lock, flags);
     1235        if (sflist->presets_locked) {
     1236                spin_unlock_irqrestore(&sflist->lock, flags);
     1237                return 0;
     1238        }
     1239        nvoices = search_zones(sflist, notep, vel, preset, bank,
     1240                               table, max_layers, 0);
     1241        if (! nvoices) {
     1242                if (preset != def_preset || bank != def_bank)
     1243                        nvoices = search_zones(sflist, notep, vel,
     1244                                               def_preset, def_bank,
     1245                                               table, max_layers, 0);
     1246        }
     1247        spin_unlock_irqrestore(&sflist->lock, flags);
     1248        return nvoices;
    12321249}
    12331250
     
    12361253 * search the first matching zone
    12371254 */
    1238 static snd_sf_zone_t *
    1239 search_first_zone(snd_sf_list_t *sflist, int bank, int preset, int key)
    1240 {
    1241     int index;
    1242     snd_sf_zone_t *zp;
    1243 
    1244     if ((index = get_index(bank, preset, key)) < 0)
    1245         return NULL;
    1246     for (zp = sflist->presets[index]; zp; zp = zp->next_instr) {
    1247         if (zp->instr == preset && zp->bank == bank)
    1248             return zp;
    1249     }
    1250     return NULL;
     1255static struct snd_sf_zone *
     1256search_first_zone(struct snd_sf_list *sflist, int bank, int preset, int key)
     1257{
     1258        int index;
     1259        struct snd_sf_zone *zp;
     1260
     1261        if ((index = get_index(bank, preset, key)) < 0)
     1262                return NULL;
     1263        for (zp = sflist->presets[index]; zp; zp = zp->next_instr) {
     1264                if (zp->instr == preset && zp->bank == bank)
     1265                        return zp;
     1266        }
     1267        return NULL;
    12511268}
    12521269
     
    12561273 */
    12571274static int
    1258 search_zones(snd_sf_list_t *sflist, int *notep, int vel, int preset, int bank, snd_sf_zone_t **table, int max_layers, int level)
    1259 {
    1260     snd_sf_zone_t *zp;
    1261     int nvoices;
    1262 
    1263     zp = search_first_zone(sflist, bank, preset, *notep);
    1264     nvoices = 0;
    1265     for (; zp; zp = zp->next_zone) {
    1266         if (*notep >= zp->v.low && *notep <= zp->v.high &&
    1267             vel >= zp->v.vellow && vel <= zp->v.velhigh) {
    1268             if (zp->mapped) {
    1269                 /* search preset mapping (aliasing) */
    1270                 int key = zp->v.fixkey;
    1271                 preset = zp->v.start;
    1272                 bank = zp->v.end;
    1273 
    1274                 if (level > 5) /* too deep alias level */
    1275                     return 0;
    1276                 if (key < 0)
    1277                     key = *notep;
    1278                 nvoices = search_zones(sflist, &key, vel,
    1279                                        preset, bank, table,
    1280                                        max_layers, level + 1);
    1281                 if (nvoices > 0)
    1282                     *notep = key;
    1283                 break;
    1284             }
    1285             table[nvoices++] = zp;
    1286             if (nvoices >= max_layers)
    1287                 break;
    1288         }
    1289     }
    1290 
    1291     return nvoices;
     1275search_zones(struct snd_sf_list *sflist, int *notep, int vel,
     1276             int preset, int bank, struct snd_sf_zone **table,
     1277             int max_layers, int level)
     1278{
     1279        struct snd_sf_zone *zp;
     1280        int nvoices;
     1281
     1282        zp = search_first_zone(sflist, bank, preset, *notep);
     1283        nvoices = 0;
     1284        for (; zp; zp = zp->next_zone) {
     1285                if (*notep >= zp->v.low && *notep <= zp->v.high &&
     1286                    vel >= zp->v.vellow && vel <= zp->v.velhigh) {
     1287                        if (zp->mapped) {
     1288                                /* search preset mapping (aliasing) */
     1289                                int key = zp->v.fixkey;
     1290                                preset = zp->v.start;
     1291                                bank = zp->v.end;
     1292
     1293                                if (level > 5) /* too deep alias level */
     1294                                        return 0;
     1295                                if (key < 0)
     1296                                        key = *notep;
     1297                                nvoices = search_zones(sflist, &key, vel,
     1298                                                       preset, bank, table,
     1299                                                       max_layers, level + 1);
     1300                                if (nvoices > 0)
     1301                                        *notep = key;
     1302                                break;
     1303                        }
     1304                        table[nvoices++] = zp;
     1305                        if (nvoices >= max_layers)
     1306                                break;
     1307                }
     1308        }
     1309
     1310        return nvoices;
    12921311}
    12931312
     
    13011320get_index(int bank, int instr, int key)
    13021321{
    1303     int index;
    1304     if (SF_IS_DRUM_BANK(bank))
    1305         index = key + SF_MAX_INSTRUMENTS;
    1306     else
    1307         index = instr;
    1308     index = index % SF_MAX_PRESETS;
    1309     if (index < 0)
    1310         return -1;
    1311     return index;
     1322        int index;
     1323        if (SF_IS_DRUM_BANK(bank))
     1324                index = key + SF_MAX_INSTRUMENTS;
     1325        else
     1326                index = instr;
     1327        index = index % SF_MAX_PRESETS;
     1328        if (index < 0)
     1329                return -1;
     1330        return index;
    13121331}
    13131332
     
    13161335 */
    13171336static void
    1318 snd_sf_init(snd_sf_list_t *sflist)
    1319 {
    1320     memset(sflist->presets, 0, sizeof(sflist->presets));
    1321 
    1322     sflist->mem_used = 0;
    1323     sflist->currsf = NULL;
    1324     sflist->open_client = -1;
    1325     sflist->fonts = NULL;
    1326     sflist->fonts_size = 0;
    1327     sflist->zone_counter = 0;
    1328     sflist->sample_counter = 0;
    1329     sflist->zone_locked = 0;
    1330     sflist->sample_locked = 0;
     1337snd_sf_init(struct snd_sf_list *sflist)
     1338{
     1339        memset(sflist->presets, 0, sizeof(sflist->presets));
     1340
     1341        sflist->mem_used = 0;
     1342        sflist->currsf = NULL;
     1343        sflist->open_client = -1;
     1344        sflist->fonts = NULL;
     1345        sflist->fonts_size = 0;
     1346        sflist->zone_counter = 0;
     1347        sflist->sample_counter = 0;
     1348        sflist->zone_locked = 0;
     1349        sflist->sample_locked = 0;
    13311350}
    13321351
     
    13351354 */
    13361355static void
    1337 snd_sf_clear(snd_sf_list_t *sflist)
    1338 {
    1339     snd_soundfont_t *sf, *nextsf;
    1340     snd_sf_zone_t *zp, *nextzp;
    1341     snd_sf_sample_t *sp, *nextsp;
    1342 
    1343     for (sf = sflist->fonts; sf; sf = nextsf) {
    1344         nextsf = sf->next;
    1345         for (zp = sf->zones; zp; zp = nextzp) {
    1346             nextzp = zp->next;
    1347             kfree(zp);
    1348         }
    1349         for (sp = sf->samples; sp; sp = nextsp) {
    1350             nextsp = sp->next;
    1351             if (sflist->callback.sample_free)
    1352                 sflist->callback.sample_free(sflist->callback.private_data, sp, sflist->memhdr);
    1353             kfree(sp);
    1354         }
    1355         kfree(sf);
    1356     }
    1357 
    1358     snd_sf_init(sflist);
     1356snd_sf_clear(struct snd_sf_list *sflist)
     1357{
     1358        struct snd_soundfont *sf, *nextsf;
     1359        struct snd_sf_zone *zp, *nextzp;
     1360        struct snd_sf_sample *sp, *nextsp;
     1361
     1362        for (sf = sflist->fonts; sf; sf = nextsf) {
     1363                nextsf = sf->next;
     1364                for (zp = sf->zones; zp; zp = nextzp) {
     1365                        nextzp = zp->next;
     1366                        kfree(zp);
     1367                }
     1368                for (sp = sf->samples; sp; sp = nextsp) {
     1369                        nextsp = sp->next;
     1370                        if (sflist->callback.sample_free)
     1371                                sflist->callback.sample_free(sflist->callback.private_data,
     1372                                                             sp, sflist->memhdr);
     1373                        kfree(sp);
     1374                }
     1375                kfree(sf);
     1376        }
     1377
     1378        snd_sf_init(sflist);
    13591379}
    13601380
     
    13631383 * Create a new sflist structure
    13641384 */
    1365 snd_sf_list_t *
    1366 snd_sf_new(snd_sf_callback_t *callback, snd_util_memhdr_t *hdr)
    1367 {
    1368     snd_sf_list_t *sflist;
    1369 
    1370     if ((sflist = kcalloc(1, sizeof(*sflist), GFP_KERNEL)) == NULL)
    1371         return NULL;
    1372 
    1373     init_MUTEX(&sflist->presets_mutex);
    1374     spin_lock_init(&sflist->lock);
    1375     sflist->sf_locked = 0;
    1376     sflist->memhdr = hdr;
    1377 
    1378     if (callback)
    1379         sflist->callback = *callback;
    1380 
    1381     snd_sf_init(sflist);
    1382     return sflist;
     1385struct snd_sf_list *
     1386snd_sf_new(struct snd_sf_callback *callback, struct snd_util_memhdr *hdr)
     1387{
     1388        struct snd_sf_list *sflist;
     1389
     1390        if ((sflist = kzalloc(sizeof(*sflist), GFP_KERNEL)) == NULL)
     1391                return NULL;
     1392
     1393        init_MUTEX(&sflist->presets_mutex);
     1394        spin_lock_init(&sflist->lock);
     1395        sflist->memhdr = hdr;
     1396
     1397        if (callback)
     1398                sflist->callback = *callback;
     1399
     1400        snd_sf_init(sflist);
     1401        return sflist;
    13831402}
    13841403
     
    13881407 */
    13891408void
    1390 snd_sf_free(snd_sf_list_t *sflist)
    1391 {
    1392     if (sflist == NULL)
    1393         return;
    1394 
    1395     lock_preset(sflist, 0);
    1396     if (sflist->callback.sample_reset)
    1397         sflist->callback.sample_reset(sflist->callback.private_data);
    1398     snd_sf_clear(sflist);
    1399     unlock_preset(sflist);
    1400 
    1401     kfree(sflist);
     1409snd_sf_free(struct snd_sf_list *sflist)
     1410{
     1411        if (sflist == NULL)
     1412                return;
     1413       
     1414        lock_preset(sflist);
     1415        if (sflist->callback.sample_reset)
     1416                sflist->callback.sample_reset(sflist->callback.private_data);
     1417        snd_sf_clear(sflist);
     1418        unlock_preset(sflist);
     1419
     1420        kfree(sflist);
    14021421}
    14031422
     
    14071426 */
    14081427int
    1409 snd_soundfont_remove_samples(snd_sf_list_t *sflist)
    1410 {
    1411     lock_preset(sflist, 0);
    1412     if (sflist->callback.sample_reset)
    1413         sflist->callback.sample_reset(sflist->callback.private_data);
    1414     snd_sf_clear(sflist);
    1415     unlock_preset(sflist);
    1416 
    1417     return 0;
     1428snd_soundfont_remove_samples(struct snd_sf_list *sflist)
     1429{
     1430        lock_preset(sflist);
     1431        if (sflist->callback.sample_reset)
     1432                sflist->callback.sample_reset(sflist->callback.private_data);
     1433        snd_sf_clear(sflist);
     1434        unlock_preset(sflist);
     1435
     1436        return 0;
    14181437}
    14191438
    14201439/*
    14211440 * Remove unlocked samples.
    1422  * The soundcard should be silet before calling this function.
     1441 * The soundcard should be silent before calling this function.
    14231442 */
    14241443int
    1425 snd_soundfont_remove_unlocked(snd_sf_list_t *sflist)
    1426 {
    1427     snd_soundfont_t *sf;
    1428     snd_sf_zone_t *zp, *nextzp;
    1429     snd_sf_sample_t *sp, *nextsp;
    1430 
    1431     if (lock_preset(sflist, 1))
    1432         return -EBUSY;
    1433 
    1434     if (sflist->callback.sample_reset)
    1435         sflist->callback.sample_reset(sflist->callback.private_data);
    1436 
    1437     /* to be sure */
    1438     memset(sflist->presets, 0, sizeof(sflist->presets));
    1439 
    1440     for (sf = sflist->fonts; sf; sf = sf->next) {
    1441         for (zp = sf->zones; zp; zp = nextzp) {
    1442             if (zp->counter < sflist->zone_locked)
    1443                 break;
    1444             nextzp = zp->next;
    1445             sf->zones = nextzp;
    1446             kfree(zp);
    1447         }
    1448 
    1449         for (sp = sf->samples; sp; sp = nextsp) {
    1450             if (sp->counter < sflist->sample_locked)
    1451                 break;
    1452             nextsp = sp->next;
    1453             sf->samples = nextsp;
    1454             sflist->mem_used -= sp->v.truesize;
    1455             if (sflist->callback.sample_free)
    1456                 sflist->callback.sample_free(sflist->callback.private_data, sp, sflist->memhdr);
    1457             kfree(sp);
    1458         }
    1459     }
    1460 
    1461     sflist->zone_counter = sflist->zone_locked;
    1462     sflist->sample_counter = sflist->sample_locked;
    1463 
    1464     rebuild_presets(sflist);
    1465 
    1466     unlock_preset(sflist);
    1467     return 0;
    1468 }
    1469 
    1470 /*
    1471  * Return the used memory size (in words)
    1472  */
    1473 int
    1474 snd_soundfont_mem_used(snd_sf_list_t *sflist)
    1475 {
    1476     return sflist->mem_used;
    1477 }
     1444snd_soundfont_remove_unlocked(struct snd_sf_list *sflist)
     1445{
     1446        struct snd_soundfont *sf;
     1447        struct snd_sf_zone *zp, *nextzp;
     1448        struct snd_sf_sample *sp, *nextsp;
     1449
     1450        lock_preset(sflist);
     1451
     1452        if (sflist->callback.sample_reset)
     1453                sflist->callback.sample_reset(sflist->callback.private_data);
     1454
     1455        /* to be sure */
     1456        memset(sflist->presets, 0, sizeof(sflist->presets));
     1457
     1458        for (sf = sflist->fonts; sf; sf = sf->next) {
     1459                for (zp = sf->zones; zp; zp = nextzp) {
     1460                        if (zp->counter < sflist->zone_locked)
     1461                                break;
     1462                        nextzp = zp->next;
     1463                        sf->zones = nextzp;
     1464                        kfree(zp);
     1465                }
     1466
     1467                for (sp = sf->samples; sp; sp = nextsp) {
     1468                        if (sp->counter < sflist->sample_locked)
     1469                                break;
     1470                        nextsp = sp->next;
     1471                        sf->samples = nextsp;
     1472                        sflist->mem_used -= sp->v.truesize;
     1473                        if (sflist->callback.sample_free)
     1474                                sflist->callback.sample_free(sflist->callback.private_data,
     1475                                                             sp, sflist->memhdr);
     1476                        kfree(sp);
     1477                }
     1478        }
     1479
     1480        sflist->zone_counter = sflist->zone_locked;
     1481        sflist->sample_counter = sflist->sample_locked;
     1482
     1483        rebuild_presets(sflist);
     1484
     1485        unlock_preset(sflist);
     1486        return 0;
     1487}
     1488
  • GPL/trunk/alsa-kernel/synth/util_mem.c

    r33 r34  
    1616 *   You should have received a copy of the GNU General Public License
    1717 *   along with this program; if not, write to the Free Software
    18  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
    19  */
    20 
    21 #define SNDRV_MAIN_OBJECT_FILE
     18 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
     19 */
     20
    2221#include <sound/driver.h>
     22#include <linux/init.h>
     23#include <linux/slab.h>
     24#include <sound/core.h>
    2325#include <sound/util_mem.h>
    2426
    2527MODULE_AUTHOR("Takashi Iwai");
    26 
    27 #define get_memblk(p)   list_entry(p, snd_util_memblk_t, list)
     28MODULE_DESCRIPTION("Generic memory management routines for soundcard memory allocation");
     29MODULE_LICENSE("GPL");
     30
     31#define get_memblk(p)   list_entry(p, struct snd_util_memblk, list)
    2832
    2933/*
    3034 * create a new memory manager
    3135 */
    32 snd_util_memhdr_t *
    33     snd_util_memhdr_new(int memsize)
    34 {
    35     snd_util_memhdr_t *hdr;
    36 
    37     hdr = kcalloc(1, sizeof(*hdr), GFP_KERNEL);
    38     if (hdr == NULL)
    39         return NULL;
    40     hdr->size = memsize;
    41     init_MUTEX(&hdr->block_mutex);
    42     INIT_LIST_HEAD(&hdr->block);
    43 
    44     return hdr;
     36struct snd_util_memhdr *
     37snd_util_memhdr_new(int memsize)
     38{
     39        struct snd_util_memhdr *hdr;
     40
     41        hdr = kzalloc(sizeof(*hdr), GFP_KERNEL);
     42        if (hdr == NULL)
     43                return NULL;
     44        hdr->size = memsize;
     45        init_MUTEX(&hdr->block_mutex);
     46        INIT_LIST_HEAD(&hdr->block);
     47
     48        return hdr;
    4549}
    4650
     
    4852 * free a memory manager
    4953 */
    50 void snd_util_memhdr_free(snd_util_memhdr_t *hdr)
    51 {
    52     struct list_head *p;
    53 
    54     snd_assert(hdr != NULL, return);
    55     /* release all blocks */
    56     while ((p = hdr->block.next) != &hdr->block) {
    57         list_del(p);
    58         kfree(get_memblk(p));
    59     }
    60     kfree(hdr);
     54void snd_util_memhdr_free(struct snd_util_memhdr *hdr)
     55{
     56        struct list_head *p;
     57
     58        snd_assert(hdr != NULL, return);
     59        /* release all blocks */
     60        while ((p = hdr->block.next) != &hdr->block) {
     61                list_del(p);
     62                kfree(get_memblk(p));
     63        }
     64        kfree(hdr);
    6165}
    6266
     
    6468 * allocate a memory block (without mutex)
    6569 */
    66 snd_util_memblk_t *
    67 __snd_util_mem_alloc(snd_util_memhdr_t *hdr, int size)
    68 {
    69     snd_util_memblk_t *blk;
    70     snd_util_unit_t units, prev_offset;
    71     struct list_head *p;
    72 
    73     snd_assert(hdr != NULL, return NULL);
    74     snd_assert(size > 0, return NULL);
    75     /* word alignment */
    76     units = size;
    77     if (units & 1)
    78         units++;
    79     if (units > hdr->size)
    80         return NULL;
    81 
    82     /* look for empty block */
    83     prev_offset = 0;
    84     list_for_each(p, &hdr->block) {
    85         blk = get_memblk(p);
    86         if (blk->offset - prev_offset >= units)
    87             goto __found;
    88         prev_offset = blk->offset + blk->size;
    89     }
    90     if (hdr->size - prev_offset < units)
    91         return NULL;
     70struct snd_util_memblk *
     71__snd_util_mem_alloc(struct snd_util_memhdr *hdr, int size)
     72{
     73        struct snd_util_memblk *blk;
     74        unsigned int units, prev_offset;
     75        struct list_head *p;
     76
     77        snd_assert(hdr != NULL, return NULL);
     78        snd_assert(size > 0, return NULL);
     79
     80        /* word alignment */
     81        units = size;
     82        if (units & 1)
     83                units++;
     84        if (units > hdr->size)
     85                return NULL;
     86
     87        /* look for empty block */
     88        prev_offset = 0;
     89        list_for_each(p, &hdr->block) {
     90                blk = get_memblk(p);
     91                if (blk->offset - prev_offset >= units)
     92                        goto __found;
     93                prev_offset = blk->offset + blk->size;
     94        }
     95        if (hdr->size - prev_offset < units)
     96                return NULL;
    9297
    9398__found:
    94     return __snd_util_memblk_new(hdr, units, p->prev);
     99        return __snd_util_memblk_new(hdr, units, p->prev);
    95100}
    96101
     
    100105 * the block is linked next to prev
    101106 */
    102 snd_util_memblk_t *
    103 __snd_util_memblk_new(snd_util_memhdr_t *hdr, snd_util_unit_t units,
    104                       struct list_head *prev)
    105 {
    106     snd_util_memblk_t *blk;
    107 
    108     blk = kmalloc(sizeof(snd_util_memblk_t) + hdr->block_extra_size, GFP_KERNEL);
    109     if (blk == NULL)
    110         return NULL;
    111 
    112     if (! prev || prev == &hdr->block)
    113         blk->offset = 0;
    114     else {
    115         snd_util_memblk_t *p = get_memblk(prev);
    116         blk->offset = p->offset + p->size;
    117     }
    118     blk->size = units;
    119     list_add(&blk->list, prev);
    120     hdr->nblocks++;
    121     hdr->used += units;
    122     return blk;
     107struct snd_util_memblk *
     108__snd_util_memblk_new(struct snd_util_memhdr *hdr, unsigned int units,
     109                      struct list_head *prev)
     110{
     111        struct snd_util_memblk *blk;
     112
     113        blk = kmalloc(sizeof(struct snd_util_memblk) + hdr->block_extra_size,
     114                      GFP_KERNEL);
     115        if (blk == NULL)
     116                return NULL;
     117
     118        if (! prev || prev == &hdr->block)
     119                blk->offset = 0;
     120        else {
     121                struct snd_util_memblk *p = get_memblk(prev);
     122                blk->offset = p->offset + p->size;
     123        }
     124        blk->size = units;
     125        list_add(&blk->list, prev);
     126        hdr->nblocks++;
     127        hdr->used += units;
     128        return blk;
    123129}
    124130
     
    127133 * allocate a memory block (with mutex)
    128134 */
    129 snd_util_memblk_t *
    130 snd_util_mem_alloc(snd_util_memhdr_t *hdr, int size)
    131 {
    132     snd_util_memblk_t *blk;
    133     down(&hdr->block_mutex);
    134     blk = __snd_util_mem_alloc(hdr, size);
    135     up(&hdr->block_mutex);
    136     return blk;
     135struct snd_util_memblk *
     136snd_util_mem_alloc(struct snd_util_memhdr *hdr, int size)
     137{
     138        struct snd_util_memblk *blk;
     139        down(&hdr->block_mutex);
     140        blk = __snd_util_mem_alloc(hdr, size);
     141        up(&hdr->block_mutex);
     142        return blk;
    137143}
    138144
     
    143149 */
    144150void
    145 __snd_util_mem_free(snd_util_memhdr_t *hdr, snd_util_memblk_t *blk)
    146 {
    147     list_del(&blk->list);
    148     hdr->nblocks--;
    149     hdr->used -= blk->size;
    150     kfree(blk);
     151__snd_util_mem_free(struct snd_util_memhdr *hdr, struct snd_util_memblk *blk)
     152{
     153        list_del(&blk->list);
     154        hdr->nblocks--;
     155        hdr->used -= blk->size;
     156        kfree(blk);
    151157}
    152158
     
    154160 * free a memory block (with mutex)
    155161 */
    156 int snd_util_mem_free(snd_util_memhdr_t *hdr, snd_util_memblk_t *blk)
    157 {
    158     snd_assert(hdr && blk, return -EINVAL);
    159 
    160     down(&hdr->block_mutex);
    161     __snd_util_mem_free(hdr, blk);
    162     up(&hdr->block_mutex);
    163     return 0;
     162int snd_util_mem_free(struct snd_util_memhdr *hdr, struct snd_util_memblk *blk)
     163{
     164        snd_assert(hdr && blk, return -EINVAL);
     165
     166        down(&hdr->block_mutex);
     167        __snd_util_mem_free(hdr, blk);
     168        up(&hdr->block_mutex);
     169        return 0;
    164170}
    165171
     
    167173 * return available memory size
    168174 */
    169 int snd_util_mem_avail(snd_util_memhdr_t *hdr)
    170 {
    171     unsigned int size;
    172     down(&hdr->block_mutex);
    173     size = hdr->size - hdr->used;
    174     up(&hdr->block_mutex);
    175     return size;
     175int snd_util_mem_avail(struct snd_util_memhdr *hdr)
     176{
     177        unsigned int size;
     178        down(&hdr->block_mutex);
     179        size = hdr->size - hdr->used;
     180        up(&hdr->block_mutex);
     181        return size;
    176182}
    177183
     
    192198static int __init alsa_util_mem_init(void)
    193199{
    194     return 0;
     200        return 0;
    195201}
    196202
Note: See TracChangeset for help on using the changeset viewer.