linux/sound/synth/emux/emux_nrpn.c
<<
>>
Prefs
   1/*
   2 *  NRPN / SYSEX callbacks for Emu8k/Emu10k1
   3 *
   4 *  Copyright (c) 1999-2000 Takashi Iwai <tiwai@suse.de>
   5 *
   6 *   This program is free software; you can redistribute it and/or modify
   7 *   it under the terms of the GNU General Public License as published by
   8 *   the Free Software Foundation; either version 2 of the License, or
   9 *   (at your option) any later version.
  10 *
  11 *   This program is distributed in the hope that it will be useful,
  12 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14 *   GNU General Public License for more details.
  15 *
  16 *   You should have received a copy of the GNU General Public License
  17 *   along with this program; if not, write to the Free Software
  18 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  19 *
  20 */
  21
  22#include "emux_voice.h"
  23#include <sound/asoundef.h>
  24
  25/*
  26 * conversion from NRPN/control parameters to Emu8000 raw parameters
  27 */
  28
  29/* NRPN / CC -> Emu8000 parameter converter */
  30struct nrpn_conv_table {
  31        int control;
  32        int effect;
  33        int (*convert)(int val);
  34};
  35
  36/* effect sensitivity */
  37
  38#define FX_CUTOFF       0
  39#define FX_RESONANCE    1
  40#define FX_ATTACK       2
  41#define FX_RELEASE      3
  42#define FX_VIBRATE      4
  43#define FX_VIBDEPTH     5
  44#define FX_VIBDELAY     6
  45#define FX_NUMS         7
  46
  47/*
  48 * convert NRPN/control values
  49 */
  50
  51static int send_converted_effect(const struct nrpn_conv_table *table,
  52                                 int num_tables,
  53                                 struct snd_emux_port *port,
  54                                 struct snd_midi_channel *chan,
  55                                 int type, int val, int mode)
  56{
  57        int i, cval;
  58        for (i = 0; i < num_tables; i++) {
  59                if (table[i].control == type) {
  60                        cval = table[i].convert(val);
  61                        snd_emux_send_effect(port, chan, table[i].effect,
  62                                             cval, mode);
  63                        return 1;
  64                }
  65        }
  66        return 0;
  67}
  68
  69#define DEF_FX_CUTOFF           170
  70#define DEF_FX_RESONANCE        6
  71#define DEF_FX_ATTACK           50
  72#define DEF_FX_RELEASE          50
  73#define DEF_FX_VIBRATE          30
  74#define DEF_FX_VIBDEPTH         4
  75#define DEF_FX_VIBDELAY         1500
  76
  77/* effect sensitivities for GS NRPN:
  78 *  adjusted for chaos 8MB soundfonts
  79 */
  80static int gs_sense[] = 
  81{
  82        DEF_FX_CUTOFF, DEF_FX_RESONANCE, DEF_FX_ATTACK, DEF_FX_RELEASE,
  83        DEF_FX_VIBRATE, DEF_FX_VIBDEPTH, DEF_FX_VIBDELAY
  84};
  85
  86/* effect sensitivies for XG controls:
  87 * adjusted for chaos 8MB soundfonts
  88 */
  89static int xg_sense[] = 
  90{
  91        DEF_FX_CUTOFF, DEF_FX_RESONANCE, DEF_FX_ATTACK, DEF_FX_RELEASE,
  92        DEF_FX_VIBRATE, DEF_FX_VIBDEPTH, DEF_FX_VIBDELAY
  93};
  94
  95
  96/*
  97 * AWE32 NRPN effects
  98 */
  99
 100static int fx_delay(int val);
 101static int fx_attack(int val);
 102static int fx_hold(int val);
 103static int fx_decay(int val);
 104static int fx_the_value(int val);
 105static int fx_twice_value(int val);
 106static int fx_conv_pitch(int val);
 107static int fx_conv_Q(int val);
 108
 109/* function for each NRPN */            /* [range]  units */
 110#define fx_env1_delay   fx_delay        /* [0,5900] 4msec */
 111#define fx_env1_attack  fx_attack       /* [0,5940] 1msec */
 112#define fx_env1_hold    fx_hold         /* [0,8191] 1msec */
 113#define fx_env1_decay   fx_decay        /* [0,5940] 4msec */
 114#define fx_env1_release fx_decay        /* [0,5940] 4msec */
 115#define fx_env1_sustain fx_the_value    /* [0,127] 0.75dB */
 116#define fx_env1_pitch   fx_the_value    /* [-127,127] 9.375cents */
 117#define fx_env1_cutoff  fx_the_value    /* [-127,127] 56.25cents */
 118
 119#define fx_env2_delay   fx_delay        /* [0,5900] 4msec */
 120#define fx_env2_attack  fx_attack       /* [0,5940] 1msec */
 121#define fx_env2_hold    fx_hold         /* [0,8191] 1msec */
 122#define fx_env2_decay   fx_decay        /* [0,5940] 4msec */
 123#define fx_env2_release fx_decay        /* [0,5940] 4msec */
 124#define fx_env2_sustain fx_the_value    /* [0,127] 0.75dB */
 125
 126#define fx_lfo1_delay   fx_delay        /* [0,5900] 4msec */
 127#define fx_lfo1_freq    fx_twice_value  /* [0,127] 84mHz */
 128#define fx_lfo1_volume  fx_twice_value  /* [0,127] 0.1875dB */
 129#define fx_lfo1_pitch   fx_the_value    /* [-127,127] 9.375cents */
 130#define fx_lfo1_cutoff  fx_twice_value  /* [-64,63] 56.25cents */
 131
 132#define fx_lfo2_delay   fx_delay        /* [0,5900] 4msec */
 133#define fx_lfo2_freq    fx_twice_value  /* [0,127] 84mHz */
 134#define fx_lfo2_pitch   fx_the_value    /* [-127,127] 9.375cents */
 135
 136#define fx_init_pitch   fx_conv_pitch   /* [-8192,8192] cents */
 137#define fx_chorus       fx_the_value    /* [0,255] -- */
 138#define fx_reverb       fx_the_value    /* [0,255] -- */
 139#define fx_cutoff       fx_twice_value  /* [0,127] 62Hz */
 140#define fx_filterQ      fx_conv_Q       /* [0,127] -- */
 141
 142static int fx_delay(int val)
 143{
 144        return (unsigned short)snd_sf_calc_parm_delay(val);
 145}
 146
 147static int fx_attack(int val)
 148{
 149        return (unsigned short)snd_sf_calc_parm_attack(val);
 150}
 151
 152static int fx_hold(int val)
 153{
 154        return (unsigned short)snd_sf_calc_parm_hold(val);
 155}
 156
 157static int fx_decay(int val)
 158{
 159        return (unsigned short)snd_sf_calc_parm_decay(val);
 160}
 161
 162static int fx_the_value(int val)
 163{
 164        return (unsigned short)(val & 0xff);
 165}
 166
 167static int fx_twice_value(int val)
 168{
 169        return (unsigned short)((val * 2) & 0xff);
 170}
 171
 172static int fx_conv_pitch(int val)
 173{
 174        return (short)(val * 4096 / 1200);
 175}
 176
 177static int fx_conv_Q(int val)
 178{
 179        return (unsigned short)((val / 8) & 0xff);
 180}
 181
 182
 183static const struct nrpn_conv_table awe_effects[] =
 184{
 185        { 0, EMUX_FX_LFO1_DELAY,        fx_lfo1_delay},
 186        { 1, EMUX_FX_LFO1_FREQ, fx_lfo1_freq},
 187        { 2, EMUX_FX_LFO2_DELAY,        fx_lfo2_delay},
 188        { 3, EMUX_FX_LFO2_FREQ, fx_lfo2_freq},
 189
 190        { 4, EMUX_FX_ENV1_DELAY,        fx_env1_delay},
 191        { 5, EMUX_FX_ENV1_ATTACK,fx_env1_attack},
 192        { 6, EMUX_FX_ENV1_HOLD, fx_env1_hold},
 193        { 7, EMUX_FX_ENV1_DECAY,        fx_env1_decay},
 194        { 8, EMUX_FX_ENV1_SUSTAIN,      fx_env1_sustain},
 195        { 9, EMUX_FX_ENV1_RELEASE,      fx_env1_release},
 196
 197        {10, EMUX_FX_ENV2_DELAY,        fx_env2_delay},
 198        {11, EMUX_FX_ENV2_ATTACK,       fx_env2_attack},
 199        {12, EMUX_FX_ENV2_HOLD, fx_env2_hold},
 200        {13, EMUX_FX_ENV2_DECAY,        fx_env2_decay},
 201        {14, EMUX_FX_ENV2_SUSTAIN,      fx_env2_sustain},
 202        {15, EMUX_FX_ENV2_RELEASE,      fx_env2_release},
 203
 204        {16, EMUX_FX_INIT_PITCH,        fx_init_pitch},
 205        {17, EMUX_FX_LFO1_PITCH,        fx_lfo1_pitch},
 206        {18, EMUX_FX_LFO2_PITCH,        fx_lfo2_pitch},
 207        {19, EMUX_FX_ENV1_PITCH,        fx_env1_pitch},
 208        {20, EMUX_FX_LFO1_VOLUME,       fx_lfo1_volume},
 209        {21, EMUX_FX_CUTOFF,            fx_cutoff},
 210        {22, EMUX_FX_FILTERQ,   fx_filterQ},
 211        {23, EMUX_FX_LFO1_CUTOFF,       fx_lfo1_cutoff},
 212        {24, EMUX_FX_ENV1_CUTOFF,       fx_env1_cutoff},
 213        {25, EMUX_FX_CHORUS,            fx_chorus},
 214        {26, EMUX_FX_REVERB,            fx_reverb},
 215};
 216
 217
 218/*
 219 * GS(SC88) NRPN effects; still experimental
 220 */
 221
 222/* cutoff: quarter semitone step, max=255 */
 223static int gs_cutoff(int val)
 224{
 225        return (val - 64) * gs_sense[FX_CUTOFF] / 50;
 226}
 227
 228/* resonance: 0 to 15(max) */
 229static int gs_filterQ(int val)
 230{
 231        return (val - 64) * gs_sense[FX_RESONANCE] / 50;
 232}
 233
 234/* attack: */
 235static int gs_attack(int val)
 236{
 237        return -(val - 64) * gs_sense[FX_ATTACK] / 50;
 238}
 239
 240/* decay: */
 241static int gs_decay(int val)
 242{
 243        return -(val - 64) * gs_sense[FX_RELEASE] / 50;
 244}
 245
 246/* release: */
 247static int gs_release(int val)
 248{
 249        return -(val - 64) * gs_sense[FX_RELEASE] / 50;
 250}
 251
 252/* vibrato freq: 0.042Hz step, max=255 */
 253static int gs_vib_rate(int val)
 254{
 255        return (val - 64) * gs_sense[FX_VIBRATE] / 50;
 256}
 257
 258/* vibrato depth: max=127, 1 octave */
 259static int gs_vib_depth(int val)
 260{
 261        return (val - 64) * gs_sense[FX_VIBDEPTH] / 50;
 262}
 263
 264/* vibrato delay: -0.725msec step */
 265static int gs_vib_delay(int val)
 266{
 267        return -(val - 64) * gs_sense[FX_VIBDELAY] / 50;
 268}
 269
 270static const struct nrpn_conv_table gs_effects[] =
 271{
 272        {32, EMUX_FX_CUTOFF,    gs_cutoff},
 273        {33, EMUX_FX_FILTERQ,   gs_filterQ},
 274        {99, EMUX_FX_ENV2_ATTACK, gs_attack},
 275        {100, EMUX_FX_ENV2_DECAY, gs_decay},
 276        {102, EMUX_FX_ENV2_RELEASE, gs_release},
 277        {8, EMUX_FX_LFO1_FREQ, gs_vib_rate},
 278        {9, EMUX_FX_LFO1_VOLUME, gs_vib_depth},
 279        {10, EMUX_FX_LFO1_DELAY, gs_vib_delay},
 280};
 281
 282
 283/*
 284 * NRPN events
 285 */
 286void
 287snd_emux_nrpn(void *p, struct snd_midi_channel *chan,
 288              struct snd_midi_channel_set *chset)
 289{
 290        struct snd_emux_port *port;
 291
 292        port = p;
 293        if (snd_BUG_ON(!port || !chan))
 294                return;
 295
 296        if (chan->control[MIDI_CTL_NONREG_PARM_NUM_MSB] == 127 &&
 297            chan->control[MIDI_CTL_NONREG_PARM_NUM_LSB] <= 26) {
 298                int val;
 299                /* Win/DOS AWE32 specific NRPNs */
 300                /* both MSB/LSB necessary */
 301                val = (chan->control[MIDI_CTL_MSB_DATA_ENTRY] << 7) |
 302                        chan->control[MIDI_CTL_LSB_DATA_ENTRY]; 
 303                val -= 8192;
 304                send_converted_effect
 305                        (awe_effects, ARRAY_SIZE(awe_effects),
 306                         port, chan, chan->control[MIDI_CTL_NONREG_PARM_NUM_LSB],
 307                         val, EMUX_FX_FLAG_SET);
 308                return;
 309        }
 310
 311        if (port->chset.midi_mode == SNDRV_MIDI_MODE_GS &&
 312            chan->control[MIDI_CTL_NONREG_PARM_NUM_MSB] == 1) {
 313                int val;
 314                /* GS specific NRPNs */
 315                /* only MSB is valid */
 316                val = chan->control[MIDI_CTL_MSB_DATA_ENTRY];
 317                send_converted_effect
 318                        (gs_effects, ARRAY_SIZE(gs_effects),
 319                         port, chan, chan->control[MIDI_CTL_NONREG_PARM_NUM_LSB],
 320                         val, EMUX_FX_FLAG_ADD);
 321                return;
 322        }
 323}
 324
 325
 326/*
 327 * XG control effects; still experimental
 328 */
 329
 330/* cutoff: quarter semitone step, max=255 */
 331static int xg_cutoff(int val)
 332{
 333        return (val - 64) * xg_sense[FX_CUTOFF] / 64;
 334}
 335
 336/* resonance: 0(open) to 15(most nasal) */
 337static int xg_filterQ(int val)
 338{
 339        return (val - 64) * xg_sense[FX_RESONANCE] / 64;
 340}
 341
 342/* attack: */
 343static int xg_attack(int val)
 344{
 345        return -(val - 64) * xg_sense[FX_ATTACK] / 64;
 346}
 347
 348/* release: */
 349static int xg_release(int val)
 350{
 351        return -(val - 64) * xg_sense[FX_RELEASE] / 64;
 352}
 353
 354static const struct nrpn_conv_table xg_effects[] =
 355{
 356        {71, EMUX_FX_CUTOFF,    xg_cutoff},
 357        {74, EMUX_FX_FILTERQ,   xg_filterQ},
 358        {72, EMUX_FX_ENV2_RELEASE, xg_release},
 359        {73, EMUX_FX_ENV2_ATTACK, xg_attack},
 360};
 361
 362int
 363snd_emux_xg_control(struct snd_emux_port *port, struct snd_midi_channel *chan,
 364                    int param)
 365{
 366        return send_converted_effect(xg_effects, ARRAY_SIZE(xg_effects),
 367                                     port, chan, param,
 368                                     chan->control[param],
 369                                     EMUX_FX_FLAG_ADD);
 370}
 371
 372/*
 373 * receive sysex
 374 */
 375void
 376snd_emux_sysex(void *p, unsigned char *buf, int len, int parsed,
 377               struct snd_midi_channel_set *chset)
 378{
 379        struct snd_emux_port *port;
 380        struct snd_emux *emu;
 381
 382        port = p;
 383        if (snd_BUG_ON(!port || !chset))
 384                return;
 385        emu = port->emu;
 386
 387        switch (parsed) {
 388        case SNDRV_MIDI_SYSEX_GS_MASTER_VOLUME:
 389                snd_emux_update_port(port, SNDRV_EMUX_UPDATE_VOLUME);
 390                break;
 391        default:
 392                if (emu->ops.sysex)
 393                        emu->ops.sysex(emu, buf, len, parsed, chset);
 394                break;
 395        }
 396}
 397
 398