Changeset 34 for GPL/trunk/alsa-kernel/synth
- Timestamp:
- Dec 11, 2005, 5:57:39 PM (20 years ago)
- Location:
- GPL/trunk/alsa-kernel/synth
- Files:
-
- 9 edited
-
emux/emux.c (modified) (4 diffs)
-
emux/emux_effect.c (modified) (6 diffs)
-
emux/emux_nrpn.c (modified) (20 diffs)
-
emux/emux_proc.c (modified) (2 diffs)
-
emux/emux_seq.c (modified) (16 diffs)
-
emux/emux_synth.c (modified) (25 diffs)
-
emux/emux_voice.h (modified) (2 diffs)
-
emux/soundfont.c (modified) (44 diffs)
-
util_mem.c (modified) (9 diffs)
Legend:
- Unmodified
- Added
- Removed
-
GPL/trunk/alsa-kernel/synth/emux/emux.c
r33 r34 23 23 #include <linux/sched.h> 24 24 #include <linux/slab.h> 25 #include <linux/string.h> 25 26 #include <sound/core.h> 26 27 #include <sound/emux_synth.h> … … 35 36 * create a new hardware dependent device for Emu8000/Emu10k1 36 37 */ 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); 38 int 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 */ 69 static 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 78 static 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 86 static void sf_sample_reset(void *private_data) 87 { 88 struct snd_emux *emu = private_data; 89 emu->ops.sample_reset(emu); 90 } 91 92 int 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); 99 132 100 133 #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(s nd_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 */ 142 int 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); 120 153 121 154 #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; 141 172 } 142 173 … … 150 181 EXPORT_SYMBOL(snd_emux_unlock_voice); 151 182 183 /* soundfont.c */ 184 EXPORT_SYMBOL(snd_sf_linear_to_log); 185 152 186 153 187 /* … … 157 191 static int __init alsa_emux_init(void) 158 192 { 159 return 0;193 return 0; 160 194 } 161 195 -
GPL/trunk/alsa-kernel/synth/emux/emux_effect.c
r33 r34 23 23 */ 24 24 25 #define __NO_VERSION__26 25 #include "emux_voice.h" 27 26 #include <linux/slab.h> … … 34 33 #define xoffsetof(type,tag) ((long)(&((type)NULL)->tag) - (long)(NULL)) 35 34 36 #define parm_offset(tag) xoffsetof(s oundfont_voice_parm_t*, tag)35 #define parm_offset(tag) xoffsetof(struct soundfont_voice_parm *, tag) 37 36 38 37 #define PARM_IS_BYTE (1 << 0) … … 51 50 52 51 static 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 */ 57 56 } 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 */ 97 96 }; 98 97 99 98 /* set byte effect value */ 100 99 static void 101 effect_set_byte(unsigned char *valp, s nd_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 else111 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;100 effect_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; 118 117 } 119 118 120 119 /* set word effect value */ 121 120 static void 122 effect_set_word(unsigned short *valp, s nd_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;121 effect_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; 135 134 } 136 135 137 136 /* address offset */ 138 137 static int 139 effect_get_offset(s nd_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_ OSSEMUL138 effect_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 155 154 /* change effects - for OSS sequencer compatibility */ 156 155 void 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); 156 snd_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); 170 170 } 171 171 #endif … … 175 175 */ 176 176 void 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; 177 snd_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; 199 200 200 201 #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++; 203 204 #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++; 206 207 #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); 227 228 } 228 229 … … 230 231 /* copy wavetable registers to voice table */ 231 232 void 232 snd_emux_setup_effect(s nd_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;233 snd_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; 247 248 #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++; 250 251 #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++; 253 254 #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 else258 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); 273 274 } 274 275 … … 277 278 */ 278 279 void 279 snd_emux_create_effect(s nd_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 }280 snd_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 294 void 295 snd_emux_delete_effect(struct snd_emux_port *p) 296 { 297 kfree(p->effect); 298 p->effect = NULL; 299 } 300 301 void 302 snd_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 } 307 308 } 308 309 -
GPL/trunk/alsa-kernel/synth/emux/emux_nrpn.c
r33 r34 16 16 * You should have received a copy of the GNU General Public License 17 17 * 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 19 19 * 20 20 */ 21 21 22 22 #include "emux_voice.h" 23 24 #define NELEM(arr) (sizeof(arr)/sizeof((arr)[0])) 23 #include <sound/asoundef.h> 25 24 26 25 /* … … 29 28 30 29 /* NRPN / CC -> Emu8000 parameter converter */ 31 typedef struct{32 int control;33 int effect;34 int (*convert)(int val);35 } nrpn_conv_table;30 struct nrpn_conv_table { 31 int control; 32 int effect; 33 int (*convert)(int val); 34 }; 36 35 37 36 /* effect sensitivity */ … … 50 49 */ 51 50 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; 51 static 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; 66 66 } 67 67 … … 77 77 * adjusted for chaos 8MB soundfonts 78 78 */ 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_VIBDELAY79 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 83 83 }; 84 84 … … 86 86 * adjusted for chaos 8MB soundfonts 87 87 */ 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_VIBDELAY88 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 92 92 }; 93 93 … … 141 141 static int fx_delay(int val) 142 142 { 143 return (unsigned short)snd_sf_calc_parm_delay(val);143 return (unsigned short)snd_sf_calc_parm_delay(val); 144 144 } 145 145 146 146 static int fx_attack(int val) 147 147 { 148 return (unsigned short)snd_sf_calc_parm_attack(val);148 return (unsigned short)snd_sf_calc_parm_attack(val); 149 149 } 150 150 151 151 static int fx_hold(int val) 152 152 { 153 return (unsigned short)snd_sf_calc_parm_hold(val);153 return (unsigned short)snd_sf_calc_parm_hold(val); 154 154 } 155 155 156 156 static int fx_decay(int val) 157 157 { 158 return (unsigned short)snd_sf_calc_parm_decay(val);158 return (unsigned short)snd_sf_calc_parm_decay(val); 159 159 } 160 160 161 161 static int fx_the_value(int val) 162 162 { 163 return (unsigned short)(val & 0xff);163 return (unsigned short)(val & 0xff); 164 164 } 165 165 166 166 static int fx_twice_value(int val) 167 167 { 168 return (unsigned short)((val * 2) & 0xff);168 return (unsigned short)((val * 2) & 0xff); 169 169 } 170 170 171 171 static int fx_conv_pitch(int val) 172 172 { 173 return (short)(val * 4096 / 1200);173 return (short)(val * 4096 / 1200); 174 174 } 175 175 176 176 static int fx_conv_Q(int val) 177 177 { 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 182 static 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 }; 217 215 218 216 … … 224 222 static int gs_cutoff(int val) 225 223 { 226 return (val - 64) * gs_sense[FX_CUTOFF] / 50;224 return (val - 64) * gs_sense[FX_CUTOFF] / 50; 227 225 } 228 226 … … 230 228 static int gs_filterQ(int val) 231 229 { 232 return (val - 64) * gs_sense[FX_RESONANCE] / 50;230 return (val - 64) * gs_sense[FX_RESONANCE] / 50; 233 231 } 234 232 … … 236 234 static int gs_attack(int val) 237 235 { 238 return -(val - 64) * gs_sense[FX_ATTACK] / 50;236 return -(val - 64) * gs_sense[FX_ATTACK] / 50; 239 237 } 240 238 … … 242 240 static int gs_decay(int val) 243 241 { 244 return -(val - 64) * gs_sense[FX_RELEASE] / 50;242 return -(val - 64) * gs_sense[FX_RELEASE] / 50; 245 243 } 246 244 … … 248 246 static int gs_release(int val) 249 247 { 250 return -(val - 64) * gs_sense[FX_RELEASE] / 50;248 return -(val - 64) * gs_sense[FX_RELEASE] / 50; 251 249 } 252 250 … … 254 252 static int gs_vib_rate(int val) 255 253 { 256 return (val - 64) * gs_sense[FX_VIBRATE] / 50;254 return (val - 64) * gs_sense[FX_VIBRATE] / 50; 257 255 } 258 256 … … 260 258 static int gs_vib_depth(int val) 261 259 { 262 return (val - 64) * gs_sense[FX_VIBDEPTH] / 50;260 return (val - 64) * gs_sense[FX_VIBDEPTH] / 50; 263 261 } 264 262 … … 266 264 static int gs_vib_delay(int val) 267 265 { 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 269 static 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 }; 284 280 285 281 … … 288 284 */ 289 285 void 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 } 286 snd_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 } 325 322 } 326 323 … … 333 330 static int xg_cutoff(int val) 334 331 { 335 return (val - 64) * xg_sense[FX_CUTOFF] / 64;332 return (val - 64) * xg_sense[FX_CUTOFF] / 64; 336 333 } 337 334 … … 339 336 static int xg_filterQ(int val) 340 337 { 341 return (val - 64) * xg_sense[FX_RESONANCE] / 64;338 return (val - 64) * xg_sense[FX_RESONANCE] / 64; 342 339 } 343 340 … … 345 342 static int xg_attack(int val) 346 343 { 347 return -(val - 64) * xg_sense[FX_ATTACK] / 64;344 return -(val - 64) * xg_sense[FX_ATTACK] / 64; 348 345 } 349 346 … … 351 348 static int xg_release(int val) 352 349 { 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 353 static 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 }; 365 360 366 361 int 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); 362 snd_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); 373 369 } 374 370 … … 377 373 */ 378 374 void 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 375 snd_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 19 19 */ 20 20 21 #define __NO_VERSION__22 21 #include <sound/driver.h> 23 22 #include <linux/wait.h> … … 32 31 33 32 static void 34 snd_emux_proc_info_read(snd_info_entry_t *entry, 35 snd_info_buffer_t*buf)33 snd_emux_proc_info_read(struct snd_info_entry *entry, 34 struct snd_info_buffer *buf) 36 35 { 37 snd_emux_t*emu;38 int i;36 struct snd_emux *emu; 37 int i; 39 38 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 } 68 67 #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 } 106 105 #endif 107 up(&emu->register_mutex);106 up(&emu->register_mutex); 108 107 } 109 108 110 109 111 void snd_emux_proc_init(s nd_emux_t *emu, snd_card_t*card, int device)110 void snd_emux_proc_init(struct snd_emux *emu, struct snd_card *card, int device) 112 111 { 113 snd_info_entry_t*entry;114 char name[64];112 struct snd_info_entry *entry; 113 char name[64]; 115 114 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; 120 119 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 else128 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; 129 128 } 130 129 131 void snd_emux_proc_free(s nd_emux_t*emu)130 void snd_emux_proc_free(struct snd_emux *emu) 132 131 { 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 } 137 136 } 138 137 -
GPL/trunk/alsa-kernel/synth/emux/emux_seq.c
r33 r34 20 20 */ 21 21 22 #define __NO_VERSION__23 22 #include "emux_voice.h" 24 23 #include <linux/slab.h> … … 27 26 /* Prototypes for static functions */ 28 27 static void free_port(void *private); 29 static void snd_emux_init_port(s nd_emux_port_t *p);30 static int snd_emux_use(void *private_data, s nd_seq_port_subscribe_t*info);31 static int snd_emux_unuse(void *private_data, s nd_seq_port_subscribe_t*info);32 static int get_client(s nd_card_t*card, int index, char *name);28 static void snd_emux_init_port(struct snd_emux_port *p); 29 static int snd_emux_use(void *private_data, struct snd_seq_port_subscribe *info); 30 static int snd_emux_unuse(void *private_data, struct snd_seq_port_subscribe *info); 31 static int get_client(struct snd_card *card, int index, char *name); 33 32 34 33 /* 35 34 * MIDI emulation operators 36 35 */ 37 static s nd_midi_op_temux_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,36 static 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, 45 44 }; 46 45 … … 55 54 */ 56 55 #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 71 61 /* 72 62 * Initialise the EMUX Synth by creating a client and registering … … 76 66 */ 77 67 int 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; 68 snd_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; 123 114 } 124 115 … … 129 120 */ 130 121 void 131 snd_emux_detach_seq(s nd_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);122 snd_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); 142 133 } 143 134 … … 147 138 */ 148 139 149 s nd_emux_port_t *150 snd_emux_create_port(s nd_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;140 struct snd_emux_port * 141 snd_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; 174 165 #ifdef SNDRV_EMUX_USE_RAW_EFFECT 175 snd_emux_create_effect(p);166 snd_emux_create_effect(p); 176 167 #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; 193 184 } 194 185 … … 200 191 free_port(void *private_data) 201 192 { 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) { 206 197 #ifdef SNDRV_EMUX_USE_RAW_EFFECT 207 snd_emux_delete_effect(p);198 snd_emux_delete_effect(p); 208 199 #endif 209 if (p->chset.channels) 210 kfree(p->chset.channels); 211 kfree(p); 212 } 200 kfree(p->chset.channels); 201 kfree(p); 202 } 213 203 } 214 204 … … 220 210 */ 221 211 static void 222 snd_emux_init_port(s nd_emux_port_t *p)223 { 224 p->drum_flags = DEFAULT_DRUM_FLAGS;225 p->volume_atten = 0;226 227 snd_emux_reset_port(p);212 snd_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); 228 218 } 229 219 … … 233 223 */ 234 224 void 235 snd_emux_reset_port(s nd_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);225 snd_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); 243 233 244 234 #ifdef SNDRV_EMUX_USE_RAW_EFFECT 245 snd_emux_clear_effect(port);235 snd_emux_clear_effect(port); 246 236 #endif 247 237 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 } 257 247 } 258 248 … … 262 252 */ 263 253 int 264 snd_emux_event_input(s nd_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;254 snd_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; 275 265 } 276 266 … … 280 270 */ 281 271 int 282 snd_emux_inc_count(s nd_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;272 snd_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; 294 284 } 295 285 … … 299 289 */ 300 290 void 301 snd_emux_dec_count(s nd_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);291 snd_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); 308 298 } 309 299 … … 313 303 */ 314 304 static int 315 snd_emux_use(void *private_data, s nd_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;305 snd_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; 330 320 } 331 321 … … 334 324 */ 335 325 static int 336 snd_emux_unuse(void *private_data, s nd_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;326 snd_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; 351 341 } 352 342 … … 356 346 */ 357 347 static int 358 get_client(s nd_card_t*card, int index, char *name)359 { 360 snd_seq_client_callback_tcallbacks;361 snd_seq_client_info_tcinfo;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;348 get_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; 381 371 } 382 372 … … 385 375 * attach virtual rawmidi devices 386 376 */ 387 int snd_emux_init_virmidi(s nd_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;377 int 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; 417 407 418 408 __error: 419 //snd_printk("error init..\n");420 snd_emux_delete_virmidi(emu);421 return -ENOMEM;422 } 423 424 int snd_emux_delete_virmidi(s nd_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 414 int 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 23 23 */ 24 24 25 #define __NO_VERSION__26 25 #include "emux_voice.h" 27 26 #include <sound/asoundef.h> … … 38 37 #define LIMITMAX(x, a) do {if ((x) > (a)) (x) = (a); } while (0) 39 38 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); 39 static 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); 42 static int get_bank(struct snd_emux_port *port, struct snd_midi_channel *chan); 43 static void terminate_note1(struct snd_emux *emu, int note, 44 struct snd_midi_channel *chan, int free); 45 static void exclusive_note_off(struct snd_emux *emu, struct snd_emux_port *port, 46 int exclass); 47 static void terminate_voice(struct snd_emux *emu, struct snd_emux_voice *vp, int free); 48 static void update_voice(struct snd_emux *emu, struct snd_emux_voice *vp, int update); 49 static void setup_voice(struct snd_emux_voice *vp); 50 static int calc_pan(struct snd_emux_voice *vp); 51 static int calc_volume(struct snd_emux_voice *vp); 52 static int calc_pitch(struct snd_emux_voice *vp); 50 53 51 54 … … 54 57 */ 55 58 void 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, ¬e, 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 }59 snd_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, ¬e, 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 } 84 87 85 88 #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); 88 91 #endif 89 92 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); 139 141 140 142 #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 } 149 151 #endif 150 152 } … … 154 156 */ 155 157 void 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); 158 snd_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); 196 197 } 197 198 … … 203 204 void snd_emux_timer_callback(unsigned long data) 204 205 { 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 } else226 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); 228 229 } 229 230 … … 232 233 */ 233 234 void 234 snd_emux_key_press(void *p, int note, int vel, s nd_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);235 snd_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); 259 260 } 260 261 … … 264 265 */ 265 266 void 266 snd_emux_update_channel(s nd_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);267 snd_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); 287 288 } 288 289 … … 291 292 */ 292 293 void 293 snd_emux_update_port(s nd_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);294 snd_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); 314 315 } 315 316 … … 320 321 */ 321 322 void 322 snd_emux_control(void *p, int type, s nd_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:323 snd_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: 340 341 #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); 344 345 #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 } 373 364 } 374 365 … … 378 369 */ 379 370 static void 380 terminate_note1(s nd_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);371 terminate_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); 394 385 } 395 386 … … 399 390 */ 400 391 void 401 snd_emux_terminate_note(void *p, int note, s nd_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);392 snd_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); 414 405 } 415 406 … … 419 410 */ 420 411 void 421 snd_emux_terminate_all(s nd_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);412 snd_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); 443 434 } 444 435 … … 448 439 */ 449 440 void 450 snd_emux_sounds_off_all(s nd_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);441 snd_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); 476 467 } 477 468 … … 482 473 */ 483 474 static void 484 exclusive_note_off(s nd_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);475 exclusive_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); 499 490 } 500 491 … … 504 495 */ 505 496 static void 506 terminate_voice(s nd_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);497 terminate_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); 517 508 } 518 509 … … 522 513 */ 523 514 static void 524 update_voice(s nd_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);515 update_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); 540 531 } 541 532 … … 543 534 #if 0 // not used 544 535 /* 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, 0x7A90536 static unsigned short voltarget[16] = { 537 0xEAC0, 0xE0C8, 0xD740, 0xCE20, 0xC560, 0xBD08, 0xB500, 0xAD58, 538 0xA5F8, 0x9EF0, 0x9830, 0x91C0, 0x8B90, 0x85A8, 0x8000, 0x7A90 548 539 }; 549 540 #endif … … 557 548 */ 558 549 static void 559 setup_voice(s nd_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;550 setup_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; 566 557 567 558 #ifdef SNDRV_EMUX_USE_RAW_EFFECT 568 snd_emux_setup_effect(vp);559 snd_emux_setup_effect(vp); 569 560 #endif 570 561 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 } else607 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; 616 607 #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 } 621 612 #endif 622 613 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 } 627 618 } 628 619 … … 631 622 */ 632 623 static 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,624 0x00,0x03,0x06,0x09,0x0c,0x0f,0x12,0x14,0x17,0x1a,0x1d,0x20,0x22,0x25,0x28,0x2a, 625 0x2d,0x30,0x32,0x35,0x37,0x3a,0x3c,0x3f,0x41,0x44,0x46,0x49,0x4b,0x4d,0x50,0x52, 626 0x54,0x57,0x59,0x5b,0x5d,0x60,0x62,0x64,0x66,0x68,0x6a,0x6c,0x6f,0x71,0x73,0x75, 627 0x77,0x79,0x7b,0x7c,0x7e,0x80,0x82,0x84,0x86,0x88,0x89,0x8b,0x8d,0x8f,0x90,0x92, 628 0x94,0x96,0x97,0x99,0x9a,0x9c,0x9e,0x9f,0xa1,0xa2,0xa4,0xa5,0xa7,0xa8,0xaa,0xab, 629 0xad,0xae,0xaf,0xb1,0xb2,0xb3,0xb5,0xb6,0xb7,0xb9,0xba,0xbb,0xbc,0xbe,0xbf,0xc0, 630 0xc1,0xc2,0xc3,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xcb,0xcc,0xcd,0xce,0xcf,0xd0,0xd1, 631 0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd7,0xd8,0xd9,0xda,0xdb,0xdc,0xdc,0xdd,0xde,0xdf, 632 0xdf,0xe0,0xe1,0xe2,0xe2,0xe3,0xe4,0xe4,0xe5,0xe6,0xe6,0xe7,0xe8,0xe8,0xe9,0xe9, 633 0xea,0xeb,0xeb,0xec,0xec,0xed,0xed,0xee,0xee,0xef,0xef,0xf0,0xf0,0xf1,0xf1,0xf1, 634 0xf2,0xf2,0xf3,0xf3,0xf3,0xf4,0xf4,0xf5,0xf5,0xf5,0xf6,0xf6,0xf6,0xf7,0xf7,0xf7, 635 0xf7,0xf8,0xf8,0xf8,0xf9,0xf9,0xf9,0xf9,0xf9,0xfa,0xfa,0xfa,0xfa,0xfb,0xfb,0xfb, 636 0xfb,0xfb,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd, 637 0xfd,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe, 638 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 639 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 649 640 }; 650 641 651 642 static int 652 calc_pan(s nd_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 643 calc_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 } 688 679 } 689 680 … … 699 690 /* tables for volume->attenuation calculation */ 700 691 static 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, 0x00692 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 714 705 }; 715 706 716 707 static 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, 0x00708 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 730 721 }; 731 722 732 723 static 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, 0x00724 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 746 737 }; 747 738 … … 751 742 */ 752 743 static int 753 calc_volume(s nd_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;744 calc_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; 788 779 789 780 #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 } 794 785 #endif 795 786 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 else807 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 */ 814 805 } 815 806 … … 822 813 823 814 static int 824 calc_pitch(s nd_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;815 calc_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; 849 840 850 841 #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 } 857 848 #endif 858 849 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 */ 867 858 } 868 859 … … 871 862 */ 872 863 static int 873 get_bank(s nd_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 }864 get_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 } 895 886 } 896 887 … … 900 891 */ 901 892 static 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); 893 get_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); 921 913 } 922 914 … … 924 916 */ 925 917 void 926 snd_emux_init_voices(s nd_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(s nd_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 else956 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(s nd_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 else971 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 } 918 snd_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 */ 940 void 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 */ 955 void 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 30 30 31 31 /* 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); 32 int snd_emux_init_seq(struct snd_emux *emu, struct snd_card *card, int index); 33 void snd_emux_detach_seq(struct snd_emux *emu); 34 struct 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); 37 void snd_emux_reset_port(struct snd_emux_port *port); 38 int snd_emux_event_input(struct snd_seq_event *ev, int direct, void *private, 39 int atomic, int hop); 40 int snd_emux_inc_count(struct snd_emux *emu); 41 void snd_emux_dec_count(struct snd_emux *emu); 42 int snd_emux_init_virmidi(struct snd_emux *emu, struct snd_card *card); 43 int snd_emux_delete_virmidi(struct snd_emux *emu); 41 44 42 45 /* Prototypes for emux_synth.c */ 43 void snd_emux_init_voices(s nd_emux_t*emu);46 void snd_emux_init_voices(struct snd_emux *emu); 44 47 45 48 void snd_emux_note_on(void *p, int note, int vel, struct snd_midi_channel *chan); 46 49 void snd_emux_note_off(void *p, int note, int vel, struct snd_midi_channel *chan); 47 50 void 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, s nd_midi_channel_t*chan);51 void snd_emux_terminate_note(void *p, int note, struct snd_midi_channel *chan); 49 52 void snd_emux_control(void *p, int type, struct snd_midi_channel *chan); 50 53 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); 54 void snd_emux_sounds_off_all(struct snd_emux_port *port); 55 void snd_emux_update_channel(struct snd_emux_port *port, 56 struct snd_midi_channel *chan, int update); 57 void snd_emux_update_port(struct snd_emux_port *port, int update); 54 58 55 59 void snd_emux_timer_callback(unsigned long data); … … 57 61 /* emux_effect.c */ 58 62 #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); 63 void snd_emux_create_effect(struct snd_emux_port *p); 64 void snd_emux_delete_effect(struct snd_emux_port *p); 65 void snd_emux_clear_effect(struct snd_emux_port *p); 66 void snd_emux_setup_effect(struct snd_emux_voice *vp); 67 void snd_emux_send_effect_oss(struct snd_emux_port *port, 68 struct snd_midi_channel *chan, int type, int val); 69 void snd_emux_send_effect(struct snd_emux_port *port, 70 struct snd_midi_channel *chan, int type, int val, int mode); 65 71 #endif 66 72 67 73 /* 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); 74 void snd_emux_sysex(void *private_data, unsigned char *buf, int len, 75 int parsed, struct snd_midi_channel_set *chset); 76 int snd_emux_xg_control(struct snd_emux_port *port, 77 struct snd_midi_channel *chan, int param); 78 void snd_emux_nrpn(void *private_data, struct snd_midi_channel *chan, 79 struct snd_midi_channel_set *chset); 71 80 72 81 /* emux_oss.c */ 73 void snd_emux_init_seq_oss(s nd_emux_t*emu);74 void snd_emux_detach_seq_oss(s nd_emux_t*emu);82 void snd_emux_init_seq_oss(struct snd_emux *emu); 83 void snd_emux_detach_seq_oss(struct snd_emux *emu); 75 84 76 85 /* emux_proc.c */ 77 86 #ifdef CONFIG_PROC_FS 78 void snd_emux_proc_init(s nd_emux_t *emu, snd_card_t*card, int device);79 void snd_emux_proc_free(s nd_emux_t*emu);87 void snd_emux_proc_init(struct snd_emux *emu, struct snd_card *card, int device); 88 void snd_emux_proc_free(struct snd_emux *emu); 80 89 #endif 81 90 82 91 #define STATE_IS_PLAYING(s) ((s) & SNDRV_EMUX_ST_ON) 83 92 93 /* emux_hwdep.c */ 94 int snd_emux_init_hwdep(struct snd_emux *emu); 95 void snd_emux_delete_hwdep(struct snd_emux *emu); 96 84 97 #endif -
GPL/trunk/alsa-kernel/synth/emux/soundfont.c
r33 r34 26 26 * Everything may change when there is an alsa way of doing things. 27 27 */ 28 #define __NO_VERSION__29 28 #include <sound/driver.h> 30 29 #include <asm/uaccess.h> … … 32 31 #include <sound/core.h> 33 32 #include <sound/soundfont.h> 33 #include <sound/seq_oss_legacy.h> 34 34 35 35 /* Prototypes for static functions */ 36 36 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); 37 static int open_patch(struct snd_sf_list *sflist, const char __user *data, 38 int count, int client); 39 static struct snd_soundfont *newsf(struct snd_sf_list *sflist, int type, char *name); 40 static int is_identical_font(struct snd_soundfont *sf, int type, unsigned char *name); 41 static int close_patch(struct snd_sf_list *sflist); 42 static int probe_data(struct snd_sf_list *sflist, int sample_id); 43 static void set_zone_counter(struct snd_sf_list *sflist, 44 struct snd_soundfont *sf, struct snd_sf_zone *zp); 45 static struct snd_sf_zone *sf_zone_new(struct snd_sf_list *sflist, 46 struct snd_soundfont *sf); 47 static void set_sample_counter(struct snd_sf_list *sflist, 48 struct snd_soundfont *sf, struct snd_sf_sample *sp); 49 static struct snd_sf_sample *sf_sample_new(struct snd_sf_list *sflist, 50 struct snd_soundfont *sf); 51 static void sf_sample_delete(struct snd_sf_list *sflist, 52 struct snd_soundfont *sf, struct snd_sf_sample *sp); 53 static int load_map(struct snd_sf_list *sflist, const void __user *data, int count); 54 static int load_info(struct snd_sf_list *sflist, const void __user *data, long count); 55 static int remove_info(struct snd_sf_list *sflist, struct snd_soundfont *sf, 56 int bank, int instr); 57 static void init_voice_info(struct soundfont_voice_info *avp); 58 static void init_voice_parm(struct soundfont_voice_parm *pp); 59 static struct snd_sf_sample *set_sample(struct snd_soundfont *sf, 60 struct soundfont_voice_info *avp); 61 static struct snd_sf_sample *find_sample(struct snd_soundfont *sf, int sample_id); 62 static int load_data(struct snd_sf_list *sflist, const void __user *data, long count); 63 static void rebuild_presets(struct snd_sf_list *sflist); 64 static void add_preset(struct snd_sf_list *sflist, struct snd_sf_zone *cur); 65 static void delete_preset(struct snd_sf_list *sflist, struct snd_sf_zone *zp); 66 static struct snd_sf_zone *search_first_zone(struct snd_sf_list *sflist, 67 int bank, int preset, int key); 68 static 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); 60 71 static int get_index(int bank, int instr, int key); 61 static void snd_sf_init(s nd_sf_list_t *sflist);62 static void snd_sf_clear(s nd_sf_list_t *sflist);72 static void snd_sf_init(struct snd_sf_list *sflist); 73 static void snd_sf_clear(struct snd_sf_list *sflist); 63 74 64 75 /* 65 76 * lock access to sflist 66 77 */ 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; 78 static void 79 lock_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); 80 86 } 81 87 … … 85 91 */ 86 92 static void 87 unlock_preset(snd_sf_list_t *sflist) 88 { 89 up(&sflist->presets_mutex); 90 sflist->sf_locked = 0; 93 unlock_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); 91 100 } 92 101 … … 96 105 */ 97 106 int 98 snd_soundfont_close_check(s nd_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;107 snd_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; 108 117 } 109 118 … … 118 127 */ 119 128 int 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; 129 snd_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; 208 215 } 209 216 … … 213 220 is_special_type(int type) 214 221 { 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); 218 225 } 219 226 … … 221 228 /* open patch; create sf list */ 222 229 static 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; 230 open_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; 252 262 } 253 263 … … 255 265 * Allocate a new soundfont structure. 256 266 */ 257 static s nd_soundfont_t *258 newsf(s nd_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;267 static struct snd_soundfont * 268 newsf(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; 289 299 } 290 300 291 301 /* check if the given name matches to the existing list */ 292 302 static int 293 is_identical_font(s nd_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));303 is_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)); 299 309 } 300 310 … … 303 313 */ 304 314 static 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; 315 close_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; 313 327 314 328 } … … 316 330 /* probe sample in the current list -- nothing to be loaded */ 317 331 static int 318 probe_data(s nd_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;332 probe_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; 327 341 } 328 342 … … 331 345 */ 332 346 static 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; 347 set_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; 338 353 } 339 354 … … 341 356 * allocate a new zone record 342 357 */ 343 static s nd_sf_zone_t*344 sf_zone_new(s nd_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;358 static struct snd_sf_zone * 359 sf_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; 357 372 } 358 373 … … 362 377 */ 363 378 static 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; 379 set_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; 369 385 } 370 386 … … 372 388 * allocate a new sample list record 373 389 */ 374 static s nd_sf_sample_t*375 sf_sample_new(s nd_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;390 static struct snd_sf_sample * 391 sf_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; 387 403 } 388 404 … … 392 408 */ 393 409 static 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 } 410 sf_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 } 401 418 } 402 419 … … 404 421 /* load voice map */ 405 422 static int 406 load_map(s nd_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_tmap;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;423 load_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; 466 483 } 467 484 … … 469 486 /* remove the present instrument layers */ 470 487 static 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; 488 remove_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; 494 512 } 495 513 … … 500 518 */ 501 519 static 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; 520 load_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; 595 605 } 596 606 … … 598 608 /* initialize voice_info record */ 599 609 static void 600 init_voice_info(s oundfont_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);610 init_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); 615 625 } 616 626 … … 622 632 */ 623 633 static void 624 init_voice_parm(s oundfont_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 } 634 init_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 } 643 653 644 654 /* search the specified sample */ 645 static s nd_sf_sample_t*646 set_sample(s nd_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 offset656 * from sample pointers. Here we calculate the actual DRAM657 * 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;655 static struct snd_sf_sample * 656 set_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; 668 678 } 669 679 670 680 /* find the sample pointer with the given id in the soundfont */ 671 static s nd_sf_sample_t*672 find_sample(s nd_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;681 static struct snd_sf_sample * 682 find_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; 684 694 } 685 695 … … 692 702 */ 693 703 static 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; 704 load_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; 753 759 } 754 760 … … 756 762 /* log2_tbl[i] = log2(i+128) * 0x10000 */ 757 763 static 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, 775 781 }; 776 782 … … 788 794 snd_sf_linear_to_log(unsigned int amount, int offset, int ratio) 789 795 { 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; 805 811 } 806 812 … … 820 826 freq_to_note(int mhz) 821 827 { 822 return snd_sf_linear_to_log(mhz, OFFSET_ABSCENT, ABSCENT_RATIO);828 return snd_sf_linear_to_log(mhz, OFFSET_ABSCENT, ABSCENT_RATIO); 823 829 } 824 830 … … 833 839 calc_rate_offset(int hz) 834 840 { 835 return snd_sf_linear_to_log(hz, OFFSET_SAMPLERATE, SAMPLERATE_RATIO);841 return snd_sf_linear_to_log(hz, OFFSET_SAMPLERATE, SAMPLERATE_RATIO); 836 842 } 837 843 … … 841 847 calc_gus_envelope_time(int rate, int start, int end) 842 848 { 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 else851 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); 853 859 } 854 860 … … 857 863 /* attack & decay/release time table (msec) */ 858 864 static 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,865 32767, 32767, 5989, 4235, 2994, 2518, 2117, 1780, 1497, 1373, 1259, 1154, 1058, 970, 890, 816, 866 707, 691, 662, 634, 607, 581, 557, 533, 510, 489, 468, 448, 429, 411, 393, 377, 867 361, 345, 331, 317, 303, 290, 278, 266, 255, 244, 234, 224, 214, 205, 196, 188, 868 180, 172, 165, 158, 151, 145, 139, 133, 127, 122, 117, 112, 107, 102, 98, 94, 869 90, 86, 82, 79, 75, 72, 69, 66, 63, 61, 58, 56, 53, 51, 49, 47, 870 45, 43, 41, 39, 37, 36, 34, 33, 31, 30, 29, 28, 26, 25, 24, 23, 871 22, 21, 20, 19, 19, 18, 17, 16, 16, 15, 15, 14, 13, 13, 12, 12, 872 11, 11, 10, 10, 10, 9, 9, 8, 8, 8, 8, 7, 7, 7, 6, 0, 867 873 }; 868 874 869 875 static 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,876 32767, 32767, 22614, 15990, 11307, 9508, 7995, 6723, 5653, 5184, 4754, 4359, 3997, 3665, 3361, 3082, 877 2828, 2765, 2648, 2535, 2428, 2325, 2226, 2132, 2042, 1955, 1872, 1793, 1717, 1644, 1574, 1507, 878 1443, 1382, 1324, 1267, 1214, 1162, 1113, 1066, 978, 936, 897, 859, 822, 787, 754, 722, 879 691, 662, 634, 607, 581, 557, 533, 510, 489, 468, 448, 429, 411, 393, 377, 361, 880 345, 331, 317, 303, 290, 278, 266, 255, 244, 234, 224, 214, 205, 196, 188, 180, 881 172, 165, 158, 151, 145, 139, 133, 127, 122, 117, 112, 107, 102, 98, 94, 90, 882 86, 82, 79, 75, 72, 69, 66, 63, 61, 58, 56, 53, 51, 49, 47, 45, 883 43, 41, 39, 37, 36, 34, 33, 31, 30, 29, 28, 26, 25, 24, 23, 22, 878 884 }; 879 885 … … 882 888 snd_sf_calc_parm_hold(int msec) 883 889 { 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; 888 894 } 889 895 … … 892 898 calc_parm_search(int msec, short *table) 893 899 { 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 else900 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; 903 909 } 904 910 … … 907 913 snd_sf_calc_parm_attack(int msec) 908 914 { 909 return calc_parm_search(msec, attack_time_tbl);915 return calc_parm_search(msec, attack_time_tbl); 910 916 } 911 917 … … 914 920 snd_sf_calc_parm_decay(int msec) 915 921 { 916 return calc_parm_search(msec, decay_time_tbl);922 return calc_parm_search(msec, decay_time_tbl); 917 923 } 918 924 919 925 int 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, 928 934 }; 929 935 … … 934 940 /* load GUS patch */ 935 941 static 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; 942 load_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; 1026 1034 #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); 1030 1038 #endif 1031 1039 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_time1037 (patch.env_rate[0], 0, patch.env_offset[0]);1038 hold = calc_gus_envelope_time1039 (patch.env_rate[1], patch.env_offset[0],1040 patch.env_offset[1]);1041 decay = calc_gus_envelope_time1042 (patch.env_rate[2], patch.env_offset[1],1043 patch.env_offset[2]);1044 release = calc_gus_envelope_time1045 (patch.env_rate[3], patch.env_offset[1],1046 patch.env_offset[4]);1047 release += calc_gus_envelope_time1048 (patch.env_rate[4], patch.env_offset[3],1049 patch.env_offset[4]);1050 release += calc_gus_envelope_time1051 (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]); 1060 1068 #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); 1066 1074 #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 else1090 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; 1105 1113 } 1106 1114 1107 1115 /* load GUS patch */ 1108 1116 int 1109 snd_soundfont_load_guspatch(s nd_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;1117 snd_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; 1117 1125 } 1118 1126 … … 1126 1134 */ 1127 1135 static void 1128 rebuild_presets(s nd_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 }1136 rebuild_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 } 1149 1157 } 1150 1158 … … 1154 1162 */ 1155 1163 static void 1156 add_preset(s nd_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;1164 add_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; 1182 1190 } 1183 1191 … … 1186 1194 */ 1187 1195 static void 1188 delete_preset(s nd_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 }1196 delete_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 } 1203 1211 } 1204 1212 … … 1212 1220 */ 1213 1221 int 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; 1222 snd_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; 1232 1249 } 1233 1250 … … 1236 1253 * search the first matching zone 1237 1254 */ 1238 static s nd_sf_zone_t*1239 search_first_zone(s nd_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;1255 static struct snd_sf_zone * 1256 search_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; 1251 1268 } 1252 1269 … … 1256 1273 */ 1257 1274 static 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; 1275 search_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; 1292 1311 } 1293 1312 … … 1301 1320 get_index(int bank, int instr, int key) 1302 1321 { 1303 int index;1304 if (SF_IS_DRUM_BANK(bank))1305 index = key + SF_MAX_INSTRUMENTS;1306 else1307 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; 1312 1331 } 1313 1332 … … 1316 1335 */ 1317 1336 static void 1318 snd_sf_init(s nd_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;1337 snd_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; 1331 1350 } 1332 1351 … … 1335 1354 */ 1336 1355 static 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); 1356 snd_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); 1359 1379 } 1360 1380 … … 1363 1383 * Create a new sflist structure 1364 1384 */ 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; 1385 struct snd_sf_list * 1386 snd_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; 1383 1402 } 1384 1403 … … 1388 1407 */ 1389 1408 void 1390 snd_sf_free(s nd_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);1409 snd_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); 1402 1421 } 1403 1422 … … 1407 1426 */ 1408 1427 int 1409 snd_soundfont_remove_samples(s nd_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;1428 snd_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; 1418 1437 } 1419 1438 1420 1439 /* 1421 1440 * Remove unlocked samples. 1422 * The soundcard should be sile t before calling this function.1441 * The soundcard should be silent before calling this function. 1423 1442 */ 1424 1443 int 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 } 1444 snd_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 16 16 * You should have received a copy of the GNU General Public License 17 17 * 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 22 21 #include <sound/driver.h> 22 #include <linux/init.h> 23 #include <linux/slab.h> 24 #include <sound/core.h> 23 25 #include <sound/util_mem.h> 24 26 25 27 MODULE_AUTHOR("Takashi Iwai"); 26 27 #define get_memblk(p) list_entry(p, snd_util_memblk_t, list) 28 MODULE_DESCRIPTION("Generic memory management routines for soundcard memory allocation"); 29 MODULE_LICENSE("GPL"); 30 31 #define get_memblk(p) list_entry(p, struct snd_util_memblk, list) 28 32 29 33 /* 30 34 * create a new memory manager 31 35 */ 32 s nd_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;36 struct snd_util_memhdr * 37 snd_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; 45 49 } 46 50 … … 48 52 * free a memory manager 49 53 */ 50 void snd_util_memhdr_free(s nd_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);54 void 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); 61 65 } 62 66 … … 64 68 * allocate a memory block (without mutex) 65 69 */ 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; 70 struct 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; 92 97 93 98 __found: 94 return __snd_util_memblk_new(hdr, units, p->prev);99 return __snd_util_memblk_new(hdr, units, p->prev); 95 100 } 96 101 … … 100 105 * the block is linked next to prev 101 106 */ 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; 107 struct 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; 123 129 } 124 130 … … 127 133 * allocate a memory block (with mutex) 128 134 */ 129 s nd_util_memblk_t*130 snd_util_mem_alloc(s nd_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;135 struct snd_util_memblk * 136 snd_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; 137 143 } 138 144 … … 143 149 */ 144 150 void 145 __snd_util_mem_free(s nd_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); 151 157 } 152 158 … … 154 160 * free a memory block (with mutex) 155 161 */ 156 int snd_util_mem_free(s nd_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;162 int 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; 164 170 } 165 171 … … 167 173 * return available memory size 168 174 */ 169 int snd_util_mem_avail(s nd_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;175 int 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; 176 182 } 177 183 … … 192 198 static int __init alsa_util_mem_init(void) 193 199 { 194 return 0;200 return 0; 195 201 } 196 202
Note:
See TracChangeset
for help on using the changeset viewer.
