0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include "emux_voice.h"
0012 #include <linux/slab.h>
0013
0014 #ifdef SNDRV_EMUX_USE_RAW_EFFECT
0015
0016
0017
0018
0019 #define xoffsetof(type,tag) ((long)(&((type)NULL)->tag) - (long)(NULL))
0020
0021 #define parm_offset(tag) xoffsetof(struct soundfont_voice_parm *, tag)
0022
0023 #define PARM_IS_BYTE (1 << 0)
0024 #define PARM_IS_WORD (1 << 1)
0025 #define PARM_IS_ALIGNED (3 << 2)
0026 #define PARM_IS_ALIGN_HI (1 << 2)
0027 #define PARM_IS_ALIGN_LO (2 << 2)
0028 #define PARM_IS_SIGNED (1 << 4)
0029
0030 #define PARM_WORD (PARM_IS_WORD)
0031 #define PARM_BYTE_LO (PARM_IS_BYTE|PARM_IS_ALIGN_LO)
0032 #define PARM_BYTE_HI (PARM_IS_BYTE|PARM_IS_ALIGN_HI)
0033 #define PARM_BYTE (PARM_IS_BYTE)
0034 #define PARM_SIGN_LO (PARM_IS_BYTE|PARM_IS_ALIGN_LO|PARM_IS_SIGNED)
0035 #define PARM_SIGN_HI (PARM_IS_BYTE|PARM_IS_ALIGN_HI|PARM_IS_SIGNED)
0036
0037 static struct emux_parm_defs {
0038 int type;
0039 int low, high;
0040 long offset;
0041 int update;
0042 } parm_defs[EMUX_NUM_EFFECTS] = {
0043 {PARM_WORD, 0, 0x8000, parm_offset(moddelay), 0},
0044 {PARM_BYTE_LO, 1, 0x80, parm_offset(modatkhld), 0},
0045 {PARM_BYTE_HI, 0, 0x7e, parm_offset(modatkhld), 0},
0046 {PARM_BYTE_LO, 1, 0x7f, parm_offset(moddcysus), 0},
0047 {PARM_BYTE_LO, 1, 0x7f, parm_offset(modrelease), 0},
0048 {PARM_BYTE_HI, 0, 0x7f, parm_offset(moddcysus), 0},
0049 {PARM_BYTE_HI, 0, 0xff, parm_offset(pefe), 0},
0050 {PARM_BYTE_LO, 0, 0xff, parm_offset(pefe), 0},
0051
0052 {PARM_WORD, 0, 0x8000, parm_offset(voldelay), 0},
0053 {PARM_BYTE_LO, 1, 0x80, parm_offset(volatkhld), 0},
0054 {PARM_BYTE_HI, 0, 0x7e, parm_offset(volatkhld), 0},
0055 {PARM_BYTE_LO, 1, 0x7f, parm_offset(voldcysus), 0},
0056 {PARM_BYTE_LO, 1, 0x7f, parm_offset(volrelease), 0},
0057 {PARM_BYTE_HI, 0, 0x7f, parm_offset(voldcysus), 0},
0058
0059 {PARM_WORD, 0, 0x8000, parm_offset(lfo1delay), 0},
0060 {PARM_BYTE_LO, 0, 0xff, parm_offset(tremfrq), SNDRV_EMUX_UPDATE_TREMFREQ},
0061 {PARM_SIGN_HI, -128, 127, parm_offset(tremfrq), SNDRV_EMUX_UPDATE_TREMFREQ},
0062 {PARM_SIGN_HI, -128, 127, parm_offset(fmmod), SNDRV_EMUX_UPDATE_FMMOD},
0063 {PARM_BYTE_LO, 0, 0xff, parm_offset(fmmod), SNDRV_EMUX_UPDATE_FMMOD},
0064
0065 {PARM_WORD, 0, 0x8000, parm_offset(lfo2delay), 0},
0066 {PARM_BYTE_LO, 0, 0xff, parm_offset(fm2frq2), SNDRV_EMUX_UPDATE_FM2FRQ2},
0067 {PARM_SIGN_HI, -128, 127, parm_offset(fm2frq2), SNDRV_EMUX_UPDATE_FM2FRQ2},
0068
0069 {PARM_WORD, 0, 0xffff, -1, SNDRV_EMUX_UPDATE_PITCH},
0070 {PARM_BYTE, 0, 0xff, parm_offset(chorus), 0},
0071 {PARM_BYTE, 0, 0xff, parm_offset(reverb), 0},
0072 {PARM_BYTE, 0, 0xff, parm_offset(cutoff), SNDRV_EMUX_UPDATE_VOLUME},
0073 {PARM_BYTE, 0, 15, parm_offset(filterQ), SNDRV_EMUX_UPDATE_Q},
0074
0075 {PARM_WORD, 0, 0xffff, -1, 0},
0076 {PARM_WORD, 0, 0xffff, -1, 0},
0077 {PARM_WORD, 0, 0xffff, -1, 0},
0078 {PARM_WORD, 0, 0xffff, -1, 0},
0079 {PARM_WORD, 0, 0xffff, -1, 0},
0080 {PARM_WORD, 0, 0xffff, -1, 0},
0081 {PARM_BYTE, 0, 0xff, -1, SNDRV_EMUX_UPDATE_VOLUME},
0082 };
0083
0084
0085 static void
0086 effect_set_byte(unsigned char *valp, struct snd_midi_channel *chan, int type)
0087 {
0088 short effect;
0089 struct snd_emux_effect_table *fx = chan->private;
0090
0091 effect = fx->val[type];
0092 if (fx->flag[type] == EMUX_FX_FLAG_ADD) {
0093 if (parm_defs[type].type & PARM_IS_SIGNED)
0094 effect += *(char*)valp;
0095 else
0096 effect += *valp;
0097 }
0098 if (effect < parm_defs[type].low)
0099 effect = parm_defs[type].low;
0100 else if (effect > parm_defs[type].high)
0101 effect = parm_defs[type].high;
0102 *valp = (unsigned char)effect;
0103 }
0104
0105
0106 static void
0107 effect_set_word(unsigned short *valp, struct snd_midi_channel *chan, int type)
0108 {
0109 int effect;
0110 struct snd_emux_effect_table *fx = chan->private;
0111
0112 effect = *(unsigned short*)&fx->val[type];
0113 if (fx->flag[type] == EMUX_FX_FLAG_ADD)
0114 effect += *valp;
0115 if (effect < parm_defs[type].low)
0116 effect = parm_defs[type].low;
0117 else if (effect > parm_defs[type].high)
0118 effect = parm_defs[type].high;
0119 *valp = (unsigned short)effect;
0120 }
0121
0122
0123 static int
0124 effect_get_offset(struct snd_midi_channel *chan, int lo, int hi, int mode)
0125 {
0126 int addr = 0;
0127 struct snd_emux_effect_table *fx = chan->private;
0128
0129 if (fx->flag[hi])
0130 addr = (short)fx->val[hi];
0131 addr = addr << 15;
0132 if (fx->flag[lo])
0133 addr += (short)fx->val[lo];
0134 if (!(mode & SNDRV_SFNT_SAMPLE_8BITS))
0135 addr /= 2;
0136 return addr;
0137 }
0138
0139 #if IS_ENABLED(CONFIG_SND_SEQUENCER_OSS)
0140
0141 void
0142 snd_emux_send_effect_oss(struct snd_emux_port *port,
0143 struct snd_midi_channel *chan, int type, int val)
0144 {
0145 int mode;
0146
0147 if (type & 0x40)
0148 mode = EMUX_FX_FLAG_OFF;
0149 else if (type & 0x80)
0150 mode = EMUX_FX_FLAG_ADD;
0151 else
0152 mode = EMUX_FX_FLAG_SET;
0153 type &= 0x3f;
0154
0155 snd_emux_send_effect(port, chan, type, val, mode);
0156 }
0157 #endif
0158
0159
0160
0161
0162 void
0163 snd_emux_send_effect(struct snd_emux_port *port, struct snd_midi_channel *chan,
0164 int type, int val, int mode)
0165 {
0166 int i;
0167 int offset;
0168 unsigned char *srcp, *origp;
0169 struct snd_emux *emu;
0170 struct snd_emux_effect_table *fx;
0171 unsigned long flags;
0172
0173 emu = port->emu;
0174 fx = chan->private;
0175 if (emu == NULL || fx == NULL)
0176 return;
0177 if (type < 0 || type >= EMUX_NUM_EFFECTS)
0178 return;
0179
0180 fx->val[type] = val;
0181 fx->flag[type] = mode;
0182
0183
0184 if (!parm_defs[type].update)
0185 return;
0186 offset = parm_defs[type].offset;
0187 if (offset < 0)
0188 return;
0189
0190 #ifdef SNDRV_LITTLE_ENDIAN
0191 if (parm_defs[type].type & PARM_IS_ALIGN_HI)
0192 offset++;
0193 #else
0194 if (parm_defs[type].type & PARM_IS_ALIGN_LO)
0195 offset++;
0196 #endif
0197
0198 spin_lock_irqsave(&emu->voice_lock, flags);
0199 for (i = 0; i < emu->max_voices; i++) {
0200 struct snd_emux_voice *vp = &emu->voices[i];
0201 if (!STATE_IS_PLAYING(vp->state) || vp->chan != chan)
0202 continue;
0203 srcp = (unsigned char*)&vp->reg.parm + offset;
0204 origp = (unsigned char*)&vp->zone->v.parm + offset;
0205 if (parm_defs[i].type & PARM_IS_BYTE) {
0206 *srcp = *origp;
0207 effect_set_byte(srcp, chan, type);
0208 } else {
0209 *(unsigned short*)srcp = *(unsigned short*)origp;
0210 effect_set_word((unsigned short*)srcp, chan, type);
0211 }
0212 }
0213 spin_unlock_irqrestore(&emu->voice_lock, flags);
0214
0215
0216 snd_emux_update_channel(port, chan, parm_defs[type].update);
0217 }
0218
0219
0220
0221 void
0222 snd_emux_setup_effect(struct snd_emux_voice *vp)
0223 {
0224 struct snd_midi_channel *chan = vp->chan;
0225 struct snd_emux_effect_table *fx;
0226 unsigned char *srcp;
0227 int i;
0228
0229 fx = chan->private;
0230 if (!fx)
0231 return;
0232
0233
0234 for (i = 0; i < EMUX_FX_END; i++) {
0235 int offset;
0236 if (!fx->flag[i])
0237 continue;
0238 offset = parm_defs[i].offset;
0239 if (offset < 0)
0240 continue;
0241 #ifdef SNDRV_LITTLE_ENDIAN
0242 if (parm_defs[i].type & PARM_IS_ALIGN_HI)
0243 offset++;
0244 #else
0245 if (parm_defs[i].type & PARM_IS_ALIGN_LO)
0246 offset++;
0247 #endif
0248 srcp = (unsigned char*)&vp->reg.parm + offset;
0249 if (parm_defs[i].type & PARM_IS_BYTE)
0250 effect_set_byte(srcp, chan, i);
0251 else
0252 effect_set_word((unsigned short*)srcp, chan, i);
0253 }
0254
0255
0256 vp->reg.start += effect_get_offset(chan, EMUX_FX_SAMPLE_START,
0257 EMUX_FX_COARSE_SAMPLE_START,
0258 vp->reg.sample_mode);
0259
0260 vp->reg.loopstart += effect_get_offset(chan, EMUX_FX_LOOP_START,
0261 EMUX_FX_COARSE_LOOP_START,
0262 vp->reg.sample_mode);
0263
0264 vp->reg.loopend += effect_get_offset(chan, EMUX_FX_LOOP_END,
0265 EMUX_FX_COARSE_LOOP_END,
0266 vp->reg.sample_mode);
0267 }
0268
0269
0270
0271
0272 void
0273 snd_emux_create_effect(struct snd_emux_port *p)
0274 {
0275 int i;
0276 p->effect = kcalloc(p->chset.max_channels,
0277 sizeof(struct snd_emux_effect_table), GFP_KERNEL);
0278 if (p->effect) {
0279 for (i = 0; i < p->chset.max_channels; i++)
0280 p->chset.channels[i].private = p->effect + i;
0281 } else {
0282 for (i = 0; i < p->chset.max_channels; i++)
0283 p->chset.channels[i].private = NULL;
0284 }
0285 }
0286
0287 void
0288 snd_emux_delete_effect(struct snd_emux_port *p)
0289 {
0290 kfree(p->effect);
0291 p->effect = NULL;
0292 }
0293
0294 void
0295 snd_emux_clear_effect(struct snd_emux_port *p)
0296 {
0297 if (p->effect) {
0298 memset(p->effect, 0, sizeof(struct snd_emux_effect_table) *
0299 p->chset.max_channels);
0300 }
0301 }
0302
0303 #endif