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
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 102 #endif 103 104 } 105 106 107 /* 108 */ 109 int snd_emux_free(s nd_emux_t*emu)110 { 111 112 113 114 115 116 117 118 119 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 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 54 55 56 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 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 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 104 snd_emux_effect_table_t*fx = chan->private;105 106 107 108 109 110 111 112 113 114 115 116 117 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 125 snd_emux_effect_table_t*fx = chan->private;126 127 128 129 130 131 132 133 134 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 142 snd_emux_effect_table_t*fx = chan->private;143 144 145 146 147 148 149 150 151 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 202 202 if (parm_defs[type].type & PARM_IS_ALIGN_HI) 203 offset++; 203 204 #else 204 205 205 if (parm_defs[type].type & PARM_IS_ALIGN_LO) 206 offset++; 206 207 #endif 207 208 209 210 snd_emux_voice_t*vp = &emu->voices[i];211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 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 237 238 239 240 241 242 243 244 245 246 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 249 249 if (parm_defs[i].type & PARM_IS_ALIGN_HI) 250 offset++; 250 251 #else 251 252 252 if (parm_defs[i].type & PARM_IS_ALIGN_LO) 253 offset++; 253 254 #endif 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 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 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 297 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 33 34 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 82 79 static int gs_sense[] = 80 { 81 DEF_FX_CUTOFF, DEF_FX_RESONANCE, DEF_FX_ATTACK, DEF_FX_RELEASE, 82 DEF_FX_VIBRATE, DEF_FX_VIBDEPTH, DEF_FX_VIBDELAY 83 83 }; 84 84 … … 86 86 * adjusted for chaos 8MB soundfonts 87 87 */ 88 static int xg_sense[] = 89 { 90 91 88 static int xg_sense[] = 89 { 90 DEF_FX_CUTOFF, DEF_FX_RESONANCE, DEF_FX_ATTACK, DEF_FX_RELEASE, 91 DEF_FX_VIBRATE, DEF_FX_VIBDEPTH, DEF_FX_VIBDELAY 92 92 }; 93 93 … … 141 141 static int fx_delay(int val) 142 142 { 143 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 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 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 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 163 return (unsigned short)(val & 0xff); 164 164 } 165 165 166 166 static int fx_twice_value(int val) 167 167 { 168 168 return (unsigned short)((val * 2) & 0xff); 169 169 } 170 170 171 171 static int fx_conv_pitch(int val) 172 172 { 173 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 224 return (val - 64) * gs_sense[FX_CUTOFF] / 50; 227 225 } 228 226 … … 230 228 static int gs_filterQ(int val) 231 229 { 232 230 return (val - 64) * gs_sense[FX_RESONANCE] / 50; 233 231 } 234 232 … … 236 234 static int gs_attack(int val) 237 235 { 238 236 return -(val - 64) * gs_sense[FX_ATTACK] / 50; 239 237 } 240 238 … … 242 240 static int gs_decay(int val) 243 241 { 244 242 return -(val - 64) * gs_sense[FX_RELEASE] / 50; 245 243 } 246 244 … … 248 246 static int gs_release(int val) 249 247 { 250 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 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 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 332 return (val - 64) * xg_sense[FX_CUTOFF] / 64; 336 333 } 337 334 … … 339 336 static int xg_filterQ(int val) 340 337 { 341 338 return (val - 64) * xg_sense[FX_RESONANCE] / 64; 342 339 } 343 340 … … 345 342 static int xg_attack(int val) 346 343 { 347 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 36 struct snd_emux *emu; 37 int i; 39 38 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 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 70 snd_emux_voice_t*vp = &emu->voices[0];71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 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 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 112 struct snd_info_entry *entry; 113 char name[64]; 115 114 116 117 118 119 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 122 123 124 125 126 127 128 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 134 135 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 39 40 41 42 43 44 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 134 135 136 137 138 139 140 141 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 152 snd_seq_port_callback_t*callback)153 { 154 snd_emux_port_t *p;155 156 157 158 if ((p = kcalloc(1,sizeof(*p), GFP_KERNEL)) == NULL) {159 160 161 162 p->chset.channels = kcalloc(max_channels, sizeof(snd_midi_channel_t), GFP_KERNEL);163 164 165 166 167 168 169 170 171 172 173 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 166 snd_emux_create_effect(p); 176 167 #endif 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 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 205 193 struct snd_emux_port *p; 194 195 p = private_data; 196 if (p) { 206 197 #ifdef SNDRV_EMUX_USE_RAW_EFFECT 207 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 225 226 227 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 238 239 240 241 242 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 235 snd_emux_clear_effect(port); 246 236 #endif 247 237 248 249 250 251 252 253 254 snd_midi_channel_t*chan = port->chset.channels + i;255 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 266 { 267 snd_emux_port_t *port;268 269 270 271 272 273 274 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 285 if (!try_inc_mod_count(emu->ops.owner))286 287 if (!try_inc_mod_count(emu->card->module)) {288 dec_mod_count(emu->ops.owner);289 __error:290 291 292 293 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 305 306 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 321 322 323 324 325 326 327 328 329 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 342 343 344 345 346 347 348 349 350 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 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 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 390 391 392 393 394 395 emu->vmidi = kcalloc(emu->midi_ports, sizeof(snd_rawmidi_t*), GFP_KERNEL);396 397 398 399 400 snd_rawmidi_t*rmidi;401 snd_virmidi_dev_t*rdev;402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 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 420 421 422 } 423 424 int snd_emux_delete_virmidi(s nd_emux_t*emu)425 { 426 427 428 429 430 431 432 433 434 435 436 437 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 60 snd_emux_voice_t*vp;61 snd_sf_zone_t*table[SNDRV_EMUX_MAX_MULTI_VOICES];62 63 snd_emux_port_t *port;64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 snd_sf_zone_t*zp = table[i];81 82 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 87 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 142 143 snd_emux_effect_table_t*fx = chan->private;144 145 146 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 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 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 237 snd_emux_t*emu;238 snd_emux_voice_t*vp;239 240 snd_emux_port_t *port;241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 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 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 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 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 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 327 328 329 330 331 332 333 334 335 336 337 338 339 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 342 343 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 383 snd_emux_voice_t*vp;384 385 386 387 388 389 390 391 392 393 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 407 408 409 410 411 412 413 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 424 snd_emux_voice_t*vp;425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 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 453 snd_emux_t*emu;454 snd_emux_voice_t*vp;455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 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 488 489 490 491 492 493 494 495 496 497 498 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 509 510 511 512 513 514 515 516 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 527 528 529 530 531 532 533 534 535 536 537 538 539 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 547 536 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 563 564 565 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 559 snd_emux_setup_effect(vp); 569 560 #endif 570 561 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 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 618 619 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 624 625 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 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 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 656 657 658 659 660 661 662 663 664 665 666 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 685 } else 686 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 702 703 704 705 706 707 708 709 710 711 712 713 692 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 693 0x63, 0x2b, 0x29, 0x28, 0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 694 0x21, 0x20, 0x1f, 0x1e, 0x1e, 0x1d, 0x1c, 0x1b, 0x1b, 0x1a, 695 0x19, 0x19, 0x18, 0x17, 0x17, 0x16, 0x16, 0x15, 0x15, 0x14, 696 0x14, 0x13, 0x13, 0x13, 0x12, 0x12, 0x11, 0x11, 0x11, 0x10, 697 0x10, 0x10, 0x0f, 0x0f, 0x0f, 0x0e, 0x0e, 0x0e, 0x0e, 0x0d, 698 0x0d, 0x0d, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0b, 0x0b, 0x0b, 699 0x0b, 0x0a, 0x0a, 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 700 0x08, 0x08, 0x08, 0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x06, 701 0x06, 0x06, 0x06, 0x06, 0x05, 0x05, 0x05, 0x05, 0x05, 0x04, 702 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02, 703 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 704 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 714 705 }; 715 706 716 707 static unsigned char voltab2[128] = { 717 718 719 720 721 722 723 724 725 726 727 728 729 708 0x32, 0x31, 0x30, 0x2f, 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x2a, 709 0x29, 0x28, 0x27, 0x26, 0x25, 0x24, 0x24, 0x23, 0x22, 0x21, 710 0x21, 0x20, 0x1f, 0x1e, 0x1e, 0x1d, 0x1c, 0x1c, 0x1b, 0x1a, 711 0x1a, 0x19, 0x19, 0x18, 0x18, 0x17, 0x16, 0x16, 0x15, 0x15, 712 0x14, 0x14, 0x13, 0x13, 0x13, 0x12, 0x12, 0x11, 0x11, 0x10, 713 0x10, 0x10, 0x0f, 0x0f, 0x0f, 0x0e, 0x0e, 0x0e, 0x0d, 0x0d, 714 0x0d, 0x0c, 0x0c, 0x0c, 0x0b, 0x0b, 0x0b, 0x0b, 0x0a, 0x0a, 715 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x08, 0x08, 0x08, 716 0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x07, 0x06, 0x06, 0x06, 717 0x06, 0x06, 0x06, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 718 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03, 719 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 720 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 730 721 }; 731 722 732 723 static unsigned char expressiontab[128] = { 733 734 735 736 737 738 739 740 741 742 743 744 745 724 0x7f, 0x6c, 0x62, 0x5a, 0x54, 0x50, 0x4b, 0x48, 0x45, 0x42, 725 0x40, 0x3d, 0x3b, 0x39, 0x38, 0x36, 0x34, 0x33, 0x31, 0x30, 726 0x2f, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, 0x27, 0x26, 0x25, 727 0x24, 0x24, 0x23, 0x22, 0x21, 0x21, 0x20, 0x1f, 0x1e, 0x1e, 728 0x1d, 0x1d, 0x1c, 0x1b, 0x1b, 0x1a, 0x1a, 0x19, 0x18, 0x18, 729 0x17, 0x17, 0x16, 0x16, 0x15, 0x15, 0x15, 0x14, 0x14, 0x13, 730 0x13, 0x12, 0x12, 0x11, 0x11, 0x11, 0x10, 0x10, 0x0f, 0x0f, 731 0x0f, 0x0e, 0x0e, 0x0e, 0x0d, 0x0d, 0x0d, 0x0c, 0x0c, 0x0c, 732 0x0b, 0x0b, 0x0b, 0x0a, 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09, 733 0x08, 0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x06, 0x06, 0x06, 734 0x06, 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 735 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 736 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 746 737 }; 747 738 … … 751 742 */ 752 743 static int 753 calc_volume(s nd_emux_voice_t*vp)754 { 755 756 757 snd_midi_channel_t*chan = vp->chan;758 snd_emux_port_t *port = vp->port;759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 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 791 snd_emux_effect_table_t*fx = chan->private;792 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 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 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 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 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 852 853 snd_emux_effect_table_t*fx = chan->private;854 855 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 860 861 862 863 864 865 866 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 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 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 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 } 945 946 /* 947 */ 948 void snd_emux_lock_voice(s nd_emux_t*emu, int voice)949 { 950 951 952 953 954 955 956 957 958 959 } 960 961 /* 962 */ 963 void snd_emux_unlock_voice(s nd_emux_t*emu, int voice)964 { 965 966 967 968 969 970 971 972 973 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 101 102 103 104 105 106 107 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 216 217 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 263 264 265 266 267 268 269 270 271 272 sf = kcalloc(1,sizeof(*sf), GFP_KERNEL);273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 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 296 297 298 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 321 322 323 324 325 326 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 350 351 352 353 354 355 356 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 381 382 383 384 385 386 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 413 if (count <sizeof(map))414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 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 603 604 605 606 607 608 609 610 611 612 613 614 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 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 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 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 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 677 678 679 680 681 682 683 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 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 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 791 792 793 794 795 796 797 798 799 800 801 802 803 804 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 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 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 844 845 846 847 848 849 850 851 852 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 860 861 862 863 864 865 866 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 871 872 873 874 875 876 877 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 885 886 887 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 895 896 897 898 899 900 901 902 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 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 922 return calc_parm_search(msec, decay_time_tbl); 917 923 } 918 924 919 925 int snd_sf_vol_table[128] = { 920 921 922 923 924 925 926 927 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 1028 1029 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 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 zone->v.parm.volatkhld = 1054 1055 1056 1057 1058 1059 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 1062 1063 1064 1065 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 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 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 1111 { 1112 1113 lock_preset(sflist, 0);1114 1115 1116 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 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 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 1160 1161 1162 1163 1164 snd_sf_zone_t*p;1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 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 1191 snd_sf_zone_t*p;1192 1193 1194 1195 1196 1197 1198 1199 1200 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 1242 snd_sf_zone_t*zp;1243 1244 1245 1246 1247 1248 1249 1250 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 1304 1305 1306 1307 1308 1309 1310 1311 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 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 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 1393 1394 1395 lock_preset(sflist, 0);1396 1397 1398 1399 1400 1401 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 1413 1414 1415 1416 1417 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 34 { 35 snd_util_memhdr_t*hdr;36 37 hdr = kcalloc(1,sizeof(*hdr), GFP_KERNEL);38 39 40 41 42 43 44 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 53 54 55 56 57 58 59 60 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 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 134 135 136 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 148 149 150 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 159 160 161 162 163 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 172 173 174 175 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 200 return 0; 195 201 } 196 202
Note:
See TracChangeset
for help on using the changeset viewer.