Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  *  NRPN / SYSEX callbacks for Emu8k/Emu10k1
0004  *
0005  *  Copyright (c) 1999-2000 Takashi Iwai <tiwai@suse.de>
0006  */
0007 
0008 #include "emux_voice.h"
0009 #include <sound/asoundef.h>
0010 
0011 /*
0012  * conversion from NRPN/control parameters to Emu8000 raw parameters
0013  */
0014 
0015 /* NRPN / CC -> Emu8000 parameter converter */
0016 struct nrpn_conv_table {
0017     int control;
0018     int effect;
0019     int (*convert)(int val);
0020 };
0021 
0022 /* effect sensitivity */
0023 
0024 #define FX_CUTOFF   0
0025 #define FX_RESONANCE    1
0026 #define FX_ATTACK   2
0027 #define FX_RELEASE  3
0028 #define FX_VIBRATE  4
0029 #define FX_VIBDEPTH 5
0030 #define FX_VIBDELAY 6
0031 #define FX_NUMS     7
0032 
0033 /*
0034  * convert NRPN/control values
0035  */
0036 
0037 static int send_converted_effect(const struct nrpn_conv_table *table,
0038                  int num_tables,
0039                  struct snd_emux_port *port,
0040                  struct snd_midi_channel *chan,
0041                  int type, int val, int mode)
0042 {
0043     int i, cval;
0044     for (i = 0; i < num_tables; i++) {
0045         if (table[i].control == type) {
0046             cval = table[i].convert(val);
0047             snd_emux_send_effect(port, chan, table[i].effect,
0048                          cval, mode);
0049             return 1;
0050         }
0051     }
0052     return 0;
0053 }
0054 
0055 #define DEF_FX_CUTOFF       170
0056 #define DEF_FX_RESONANCE    6
0057 #define DEF_FX_ATTACK       50
0058 #define DEF_FX_RELEASE      50
0059 #define DEF_FX_VIBRATE      30
0060 #define DEF_FX_VIBDEPTH     4
0061 #define DEF_FX_VIBDELAY     1500
0062 
0063 /* effect sensitivities for GS NRPN:
0064  *  adjusted for chaos 8MB soundfonts
0065  */
0066 static const int gs_sense[] =
0067 {
0068     DEF_FX_CUTOFF, DEF_FX_RESONANCE, DEF_FX_ATTACK, DEF_FX_RELEASE,
0069     DEF_FX_VIBRATE, DEF_FX_VIBDEPTH, DEF_FX_VIBDELAY
0070 };
0071 
0072 /* effect sensitivities for XG controls:
0073  * adjusted for chaos 8MB soundfonts
0074  */
0075 static const int xg_sense[] =
0076 {
0077     DEF_FX_CUTOFF, DEF_FX_RESONANCE, DEF_FX_ATTACK, DEF_FX_RELEASE,
0078     DEF_FX_VIBRATE, DEF_FX_VIBDEPTH, DEF_FX_VIBDELAY
0079 };
0080 
0081 
0082 /*
0083  * AWE32 NRPN effects
0084  */
0085 
0086 static int fx_delay(int val);
0087 static int fx_attack(int val);
0088 static int fx_hold(int val);
0089 static int fx_decay(int val);
0090 static int fx_the_value(int val);
0091 static int fx_twice_value(int val);
0092 static int fx_conv_pitch(int val);
0093 static int fx_conv_Q(int val);
0094 
0095 /* function for each NRPN */        /* [range]  units */
0096 #define fx_env1_delay   fx_delay    /* [0,5900] 4msec */
0097 #define fx_env1_attack  fx_attack   /* [0,5940] 1msec */
0098 #define fx_env1_hold    fx_hold     /* [0,8191] 1msec */
0099 #define fx_env1_decay   fx_decay    /* [0,5940] 4msec */
0100 #define fx_env1_release fx_decay    /* [0,5940] 4msec */
0101 #define fx_env1_sustain fx_the_value    /* [0,127] 0.75dB */
0102 #define fx_env1_pitch   fx_the_value    /* [-127,127] 9.375cents */
0103 #define fx_env1_cutoff  fx_the_value    /* [-127,127] 56.25cents */
0104 
0105 #define fx_env2_delay   fx_delay    /* [0,5900] 4msec */
0106 #define fx_env2_attack  fx_attack   /* [0,5940] 1msec */
0107 #define fx_env2_hold    fx_hold     /* [0,8191] 1msec */
0108 #define fx_env2_decay   fx_decay    /* [0,5940] 4msec */
0109 #define fx_env2_release fx_decay    /* [0,5940] 4msec */
0110 #define fx_env2_sustain fx_the_value    /* [0,127] 0.75dB */
0111 
0112 #define fx_lfo1_delay   fx_delay    /* [0,5900] 4msec */
0113 #define fx_lfo1_freq    fx_twice_value  /* [0,127] 84mHz */
0114 #define fx_lfo1_volume  fx_twice_value  /* [0,127] 0.1875dB */
0115 #define fx_lfo1_pitch   fx_the_value    /* [-127,127] 9.375cents */
0116 #define fx_lfo1_cutoff  fx_twice_value  /* [-64,63] 56.25cents */
0117 
0118 #define fx_lfo2_delay   fx_delay    /* [0,5900] 4msec */
0119 #define fx_lfo2_freq    fx_twice_value  /* [0,127] 84mHz */
0120 #define fx_lfo2_pitch   fx_the_value    /* [-127,127] 9.375cents */
0121 
0122 #define fx_init_pitch   fx_conv_pitch   /* [-8192,8192] cents */
0123 #define fx_chorus   fx_the_value    /* [0,255] -- */
0124 #define fx_reverb   fx_the_value    /* [0,255] -- */
0125 #define fx_cutoff   fx_twice_value  /* [0,127] 62Hz */
0126 #define fx_filterQ  fx_conv_Q   /* [0,127] -- */
0127 
0128 static int fx_delay(int val)
0129 {
0130     return (unsigned short)snd_sf_calc_parm_delay(val);
0131 }
0132 
0133 static int fx_attack(int val)
0134 {
0135     return (unsigned short)snd_sf_calc_parm_attack(val);
0136 }
0137 
0138 static int fx_hold(int val)
0139 {
0140     return (unsigned short)snd_sf_calc_parm_hold(val);
0141 }
0142 
0143 static int fx_decay(int val)
0144 {
0145     return (unsigned short)snd_sf_calc_parm_decay(val);
0146 }
0147 
0148 static int fx_the_value(int val)
0149 {
0150     return (unsigned short)(val & 0xff);
0151 }
0152 
0153 static int fx_twice_value(int val)
0154 {
0155     return (unsigned short)((val * 2) & 0xff);
0156 }
0157 
0158 static int fx_conv_pitch(int val)
0159 {
0160     return (short)(val * 4096 / 1200);
0161 }
0162 
0163 static int fx_conv_Q(int val)
0164 {
0165     return (unsigned short)((val / 8) & 0xff);
0166 }
0167 
0168 
0169 static const struct nrpn_conv_table awe_effects[] =
0170 {
0171     { 0, EMUX_FX_LFO1_DELAY,    fx_lfo1_delay},
0172     { 1, EMUX_FX_LFO1_FREQ, fx_lfo1_freq},
0173     { 2, EMUX_FX_LFO2_DELAY,    fx_lfo2_delay},
0174     { 3, EMUX_FX_LFO2_FREQ, fx_lfo2_freq},
0175 
0176     { 4, EMUX_FX_ENV1_DELAY,    fx_env1_delay},
0177     { 5, EMUX_FX_ENV1_ATTACK,fx_env1_attack},
0178     { 6, EMUX_FX_ENV1_HOLD, fx_env1_hold},
0179     { 7, EMUX_FX_ENV1_DECAY,    fx_env1_decay},
0180     { 8, EMUX_FX_ENV1_SUSTAIN,  fx_env1_sustain},
0181     { 9, EMUX_FX_ENV1_RELEASE,  fx_env1_release},
0182 
0183     {10, EMUX_FX_ENV2_DELAY,    fx_env2_delay},
0184     {11, EMUX_FX_ENV2_ATTACK,   fx_env2_attack},
0185     {12, EMUX_FX_ENV2_HOLD, fx_env2_hold},
0186     {13, EMUX_FX_ENV2_DECAY,    fx_env2_decay},
0187     {14, EMUX_FX_ENV2_SUSTAIN,  fx_env2_sustain},
0188     {15, EMUX_FX_ENV2_RELEASE,  fx_env2_release},
0189 
0190     {16, EMUX_FX_INIT_PITCH,    fx_init_pitch},
0191     {17, EMUX_FX_LFO1_PITCH,    fx_lfo1_pitch},
0192     {18, EMUX_FX_LFO2_PITCH,    fx_lfo2_pitch},
0193     {19, EMUX_FX_ENV1_PITCH,    fx_env1_pitch},
0194     {20, EMUX_FX_LFO1_VOLUME,   fx_lfo1_volume},
0195     {21, EMUX_FX_CUTOFF,        fx_cutoff},
0196     {22, EMUX_FX_FILTERQ,   fx_filterQ},
0197     {23, EMUX_FX_LFO1_CUTOFF,   fx_lfo1_cutoff},
0198     {24, EMUX_FX_ENV1_CUTOFF,   fx_env1_cutoff},
0199     {25, EMUX_FX_CHORUS,        fx_chorus},
0200     {26, EMUX_FX_REVERB,        fx_reverb},
0201 };
0202 
0203 
0204 /*
0205  * GS(SC88) NRPN effects; still experimental
0206  */
0207 
0208 /* cutoff: quarter semitone step, max=255 */
0209 static int gs_cutoff(int val)
0210 {
0211     return (val - 64) * gs_sense[FX_CUTOFF] / 50;
0212 }
0213 
0214 /* resonance: 0 to 15(max) */
0215 static int gs_filterQ(int val)
0216 {
0217     return (val - 64) * gs_sense[FX_RESONANCE] / 50;
0218 }
0219 
0220 /* attack: */
0221 static int gs_attack(int val)
0222 {
0223     return -(val - 64) * gs_sense[FX_ATTACK] / 50;
0224 }
0225 
0226 /* decay: */
0227 static int gs_decay(int val)
0228 {
0229     return -(val - 64) * gs_sense[FX_RELEASE] / 50;
0230 }
0231 
0232 /* release: */
0233 static int gs_release(int val)
0234 {
0235     return -(val - 64) * gs_sense[FX_RELEASE] / 50;
0236 }
0237 
0238 /* vibrato freq: 0.042Hz step, max=255 */
0239 static int gs_vib_rate(int val)
0240 {
0241     return (val - 64) * gs_sense[FX_VIBRATE] / 50;
0242 }
0243 
0244 /* vibrato depth: max=127, 1 octave */
0245 static int gs_vib_depth(int val)
0246 {
0247     return (val - 64) * gs_sense[FX_VIBDEPTH] / 50;
0248 }
0249 
0250 /* vibrato delay: -0.725msec step */
0251 static int gs_vib_delay(int val)
0252 {
0253     return -(val - 64) * gs_sense[FX_VIBDELAY] / 50;
0254 }
0255 
0256 static const struct nrpn_conv_table gs_effects[] =
0257 {
0258     {32, EMUX_FX_CUTOFF,    gs_cutoff},
0259     {33, EMUX_FX_FILTERQ,   gs_filterQ},
0260     {99, EMUX_FX_ENV2_ATTACK, gs_attack},
0261     {100, EMUX_FX_ENV2_DECAY, gs_decay},
0262     {102, EMUX_FX_ENV2_RELEASE, gs_release},
0263     {8, EMUX_FX_LFO1_FREQ, gs_vib_rate},
0264     {9, EMUX_FX_LFO1_VOLUME, gs_vib_depth},
0265     {10, EMUX_FX_LFO1_DELAY, gs_vib_delay},
0266 };
0267 
0268 
0269 /*
0270  * NRPN events
0271  */
0272 void
0273 snd_emux_nrpn(void *p, struct snd_midi_channel *chan,
0274           struct snd_midi_channel_set *chset)
0275 {
0276     struct snd_emux_port *port;
0277 
0278     port = p;
0279     if (snd_BUG_ON(!port || !chan))
0280         return;
0281 
0282     if (chan->control[MIDI_CTL_NONREG_PARM_NUM_MSB] == 127 &&
0283         chan->control[MIDI_CTL_NONREG_PARM_NUM_LSB] <= 26) {
0284         int val;
0285         /* Win/DOS AWE32 specific NRPNs */
0286         /* both MSB/LSB necessary */
0287         val = (chan->control[MIDI_CTL_MSB_DATA_ENTRY] << 7) |
0288             chan->control[MIDI_CTL_LSB_DATA_ENTRY]; 
0289         val -= 8192;
0290         send_converted_effect
0291             (awe_effects, ARRAY_SIZE(awe_effects),
0292              port, chan, chan->control[MIDI_CTL_NONREG_PARM_NUM_LSB],
0293              val, EMUX_FX_FLAG_SET);
0294         return;
0295     }
0296 
0297     if (port->chset.midi_mode == SNDRV_MIDI_MODE_GS &&
0298         chan->control[MIDI_CTL_NONREG_PARM_NUM_MSB] == 1) {
0299         int val;
0300         /* GS specific NRPNs */
0301         /* only MSB is valid */
0302         val = chan->control[MIDI_CTL_MSB_DATA_ENTRY];
0303         send_converted_effect
0304             (gs_effects, ARRAY_SIZE(gs_effects),
0305              port, chan, chan->control[MIDI_CTL_NONREG_PARM_NUM_LSB],
0306              val, EMUX_FX_FLAG_ADD);
0307         return;
0308     }
0309 }
0310 
0311 
0312 /*
0313  * XG control effects; still experimental
0314  */
0315 
0316 /* cutoff: quarter semitone step, max=255 */
0317 static int xg_cutoff(int val)
0318 {
0319     return (val - 64) * xg_sense[FX_CUTOFF] / 64;
0320 }
0321 
0322 /* resonance: 0(open) to 15(most nasal) */
0323 static int xg_filterQ(int val)
0324 {
0325     return (val - 64) * xg_sense[FX_RESONANCE] / 64;
0326 }
0327 
0328 /* attack: */
0329 static int xg_attack(int val)
0330 {
0331     return -(val - 64) * xg_sense[FX_ATTACK] / 64;
0332 }
0333 
0334 /* release: */
0335 static int xg_release(int val)
0336 {
0337     return -(val - 64) * xg_sense[FX_RELEASE] / 64;
0338 }
0339 
0340 static const struct nrpn_conv_table xg_effects[] =
0341 {
0342     {71, EMUX_FX_CUTOFF,    xg_cutoff},
0343     {74, EMUX_FX_FILTERQ,   xg_filterQ},
0344     {72, EMUX_FX_ENV2_RELEASE, xg_release},
0345     {73, EMUX_FX_ENV2_ATTACK, xg_attack},
0346 };
0347 
0348 int
0349 snd_emux_xg_control(struct snd_emux_port *port, struct snd_midi_channel *chan,
0350             int param)
0351 {
0352     return send_converted_effect(xg_effects, ARRAY_SIZE(xg_effects),
0353                      port, chan, param,
0354                      chan->control[param],
0355                      EMUX_FX_FLAG_ADD);
0356 }
0357 
0358 /*
0359  * receive sysex
0360  */
0361 void
0362 snd_emux_sysex(void *p, unsigned char *buf, int len, int parsed,
0363            struct snd_midi_channel_set *chset)
0364 {
0365     struct snd_emux_port *port;
0366     struct snd_emux *emu;
0367 
0368     port = p;
0369     if (snd_BUG_ON(!port || !chset))
0370         return;
0371     emu = port->emu;
0372 
0373     switch (parsed) {
0374     case SNDRV_MIDI_SYSEX_GS_MASTER_VOLUME:
0375         snd_emux_update_port(port, SNDRV_EMUX_UPDATE_VOLUME);
0376         break;
0377     default:
0378         if (emu->ops.sysex)
0379             emu->ops.sysex(emu, buf, len, parsed, chset);
0380         break;
0381     }
0382 }
0383