linux/sound/isa/sb/emu8000_callback.c
<<
>>
Prefs
   1/*
   2 *  synth callback routines for the emu8000 (AWE32/64)
   3 *
   4 *  Copyright (C) 1999 Steve Ratcliffe
   5 *  Copyright (C) 1999-2000 Takashi Iwai <tiwai@suse.de>
   6 *
   7 *   This program is free software; you can redistribute it and/or modify
   8 *   it under the terms of the GNU General Public License as published by
   9 *   the Free Software Foundation; either version 2 of the License, or
  10 *   (at your option) any later version.
  11 *
  12 *   This program is distributed in the hope that it will be useful,
  13 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15 *   GNU General Public License for more details.
  16 *
  17 *   You should have received a copy of the GNU General Public License
  18 *   along with this program; if not, write to the Free Software
  19 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  20 */
  21
  22#include "emu8000_local.h"
  23#include <linux/export.h>
  24#include <sound/asoundef.h>
  25
  26/*
  27 * prototypes
  28 */
  29static struct snd_emux_voice *get_voice(struct snd_emux *emu,
  30                                        struct snd_emux_port *port);
  31static int start_voice(struct snd_emux_voice *vp);
  32static void trigger_voice(struct snd_emux_voice *vp);
  33static void release_voice(struct snd_emux_voice *vp);
  34static void update_voice(struct snd_emux_voice *vp, int update);
  35static void reset_voice(struct snd_emux *emu, int ch);
  36static void terminate_voice(struct snd_emux_voice *vp);
  37static void sysex(struct snd_emux *emu, char *buf, int len, int parsed,
  38                  struct snd_midi_channel_set *chset);
  39#if IS_ENABLED(CONFIG_SND_SEQUENCER_OSS)
  40static int oss_ioctl(struct snd_emux *emu, int cmd, int p1, int p2);
  41#endif
  42static int load_fx(struct snd_emux *emu, int type, int mode,
  43                   const void __user *buf, long len);
  44
  45static void set_pitch(struct snd_emu8000 *hw, struct snd_emux_voice *vp);
  46static void set_volume(struct snd_emu8000 *hw, struct snd_emux_voice *vp);
  47static void set_pan(struct snd_emu8000 *hw, struct snd_emux_voice *vp);
  48static void set_fmmod(struct snd_emu8000 *hw, struct snd_emux_voice *vp);
  49static void set_tremfreq(struct snd_emu8000 *hw, struct snd_emux_voice *vp);
  50static void set_fm2frq2(struct snd_emu8000 *hw, struct snd_emux_voice *vp);
  51static void set_filterQ(struct snd_emu8000 *hw, struct snd_emux_voice *vp);
  52static void snd_emu8000_tweak_voice(struct snd_emu8000 *emu, int ch);
  53
  54/*
  55 * Ensure a value is between two points
  56 * macro evaluates its args more than once, so changed to upper-case.
  57 */
  58#define LIMITVALUE(x, a, b) do { if ((x) < (a)) (x) = (a); else if ((x) > (b)) (x) = (b); } while (0)
  59#define LIMITMAX(x, a) do {if ((x) > (a)) (x) = (a); } while (0)
  60
  61
  62/*
  63 * set up operators
  64 */
  65static const struct snd_emux_operators emu8000_ops = {
  66        .owner =        THIS_MODULE,
  67        .get_voice =    get_voice,
  68        .prepare =      start_voice,
  69        .trigger =      trigger_voice,
  70        .release =      release_voice,
  71        .update =       update_voice,
  72        .terminate =    terminate_voice,
  73        .reset =        reset_voice,
  74        .sample_new =   snd_emu8000_sample_new,
  75        .sample_free =  snd_emu8000_sample_free,
  76        .sample_reset = snd_emu8000_sample_reset,
  77        .load_fx =      load_fx,
  78        .sysex =        sysex,
  79#if IS_ENABLED(CONFIG_SND_SEQUENCER_OSS)
  80        .oss_ioctl =    oss_ioctl,
  81#endif
  82};
  83
  84void
  85snd_emu8000_ops_setup(struct snd_emu8000 *hw)
  86{
  87        hw->emu->ops = emu8000_ops;
  88}
  89
  90
  91
  92/*
  93 * Terminate a voice
  94 */
  95static void
  96release_voice(struct snd_emux_voice *vp)
  97{
  98        int dcysusv;
  99        struct snd_emu8000 *hw;
 100
 101        hw = vp->hw;
 102        dcysusv = 0x8000 | (unsigned char)vp->reg.parm.modrelease;
 103        EMU8000_DCYSUS_WRITE(hw, vp->ch, dcysusv);
 104        dcysusv = 0x8000 | (unsigned char)vp->reg.parm.volrelease;
 105        EMU8000_DCYSUSV_WRITE(hw, vp->ch, dcysusv);
 106}
 107
 108
 109/*
 110 */
 111static void
 112terminate_voice(struct snd_emux_voice *vp)
 113{
 114        struct snd_emu8000 *hw; 
 115
 116        hw = vp->hw;
 117        EMU8000_DCYSUSV_WRITE(hw, vp->ch, 0x807F);
 118}
 119
 120
 121/*
 122 */
 123static void
 124update_voice(struct snd_emux_voice *vp, int update)
 125{
 126        struct snd_emu8000 *hw;
 127
 128        hw = vp->hw;
 129        if (update & SNDRV_EMUX_UPDATE_VOLUME)
 130                set_volume(hw, vp);
 131        if (update & SNDRV_EMUX_UPDATE_PITCH)
 132                set_pitch(hw, vp);
 133        if ((update & SNDRV_EMUX_UPDATE_PAN) &&
 134            vp->port->ctrls[EMUX_MD_REALTIME_PAN])
 135                set_pan(hw, vp);
 136        if (update & SNDRV_EMUX_UPDATE_FMMOD)
 137                set_fmmod(hw, vp);
 138        if (update & SNDRV_EMUX_UPDATE_TREMFREQ)
 139                set_tremfreq(hw, vp);
 140        if (update & SNDRV_EMUX_UPDATE_FM2FRQ2)
 141                set_fm2frq2(hw, vp);
 142        if (update & SNDRV_EMUX_UPDATE_Q)
 143                set_filterQ(hw, vp);
 144}
 145
 146
 147/*
 148 * Find a channel (voice) within the EMU that is not in use or at least
 149 * less in use than other channels.  Always returns a valid pointer
 150 * no matter what.  If there is a real shortage of voices then one
 151 * will be cut. Such is life.
 152 *
 153 * The channel index (vp->ch) must be initialized in this routine.
 154 * In Emu8k, it is identical with the array index.
 155 */
 156static struct snd_emux_voice *
 157get_voice(struct snd_emux *emu, struct snd_emux_port *port)
 158{
 159        int  i;
 160        struct snd_emux_voice *vp;
 161        struct snd_emu8000 *hw;
 162
 163        /* what we are looking for, in order of preference */
 164        enum {
 165                OFF=0, RELEASED, PLAYING, END
 166        };
 167
 168        /* Keeps track of what we are finding */
 169        struct best {
 170                unsigned int  time;
 171                int voice;
 172        } best[END];
 173        struct best *bp;
 174
 175        hw = emu->hw;
 176
 177        for (i = 0; i < END; i++) {
 178                best[i].time = (unsigned int)(-1); /* XXX MAX_?INT really */
 179                best[i].voice = -1;
 180        }
 181
 182        /*
 183         * Go through them all and get a best one to use.
 184         */
 185        for (i = 0; i < emu->max_voices; i++) {
 186                int state, val;
 187
 188                vp = &emu->voices[i];
 189                state = vp->state;
 190
 191                if (state == SNDRV_EMUX_ST_OFF)
 192                        bp = best + OFF;
 193                else if (state == SNDRV_EMUX_ST_RELEASED ||
 194                         state == SNDRV_EMUX_ST_PENDING) {
 195                        bp = best + RELEASED;
 196                        val = (EMU8000_CVCF_READ(hw, vp->ch) >> 16) & 0xffff;
 197                        if (! val)
 198                                bp = best + OFF;
 199                }
 200                else if (state & SNDRV_EMUX_ST_ON)
 201                        bp = best + PLAYING;
 202                else
 203                        continue;
 204
 205                /* check if sample is finished playing (non-looping only) */
 206                if (state != SNDRV_EMUX_ST_OFF &&
 207                    (vp->reg.sample_mode & SNDRV_SFNT_SAMPLE_SINGLESHOT)) {
 208                        val = EMU8000_CCCA_READ(hw, vp->ch) & 0xffffff;
 209                        if (val >= vp->reg.loopstart)
 210                                bp = best + OFF;
 211                }
 212
 213                if (vp->time < bp->time) {
 214                        bp->time = vp->time;
 215                        bp->voice = i;
 216                }
 217        }
 218
 219        for (i = 0; i < END; i++) {
 220                if (best[i].voice >= 0) {
 221                        vp = &emu->voices[best[i].voice];
 222                        vp->ch = best[i].voice;
 223                        return vp;
 224                }
 225        }
 226
 227        /* not found */
 228        return NULL;
 229}
 230
 231/*
 232 */
 233static int
 234start_voice(struct snd_emux_voice *vp)
 235{
 236        unsigned int temp;
 237        int ch;
 238        int addr;
 239        struct snd_midi_channel *chan;
 240        struct snd_emu8000 *hw;
 241
 242        hw = vp->hw;
 243        ch = vp->ch;
 244        chan = vp->chan;
 245
 246        /* channel to be silent and idle */
 247        EMU8000_DCYSUSV_WRITE(hw, ch, 0x0080);
 248        EMU8000_VTFT_WRITE(hw, ch, 0x0000FFFF);
 249        EMU8000_CVCF_WRITE(hw, ch, 0x0000FFFF);
 250        EMU8000_PTRX_WRITE(hw, ch, 0);
 251        EMU8000_CPF_WRITE(hw, ch, 0);
 252
 253        /* set pitch offset */
 254        set_pitch(hw, vp);
 255
 256        /* set envelope parameters */
 257        EMU8000_ENVVAL_WRITE(hw, ch, vp->reg.parm.moddelay);
 258        EMU8000_ATKHLD_WRITE(hw, ch, vp->reg.parm.modatkhld);
 259        EMU8000_DCYSUS_WRITE(hw, ch, vp->reg.parm.moddcysus);
 260        EMU8000_ENVVOL_WRITE(hw, ch, vp->reg.parm.voldelay);
 261        EMU8000_ATKHLDV_WRITE(hw, ch, vp->reg.parm.volatkhld);
 262        /* decay/sustain parameter for volume envelope is used
 263           for triggerg the voice */
 264
 265        /* cutoff and volume */
 266        set_volume(hw, vp);
 267
 268        /* modulation envelope heights */
 269        EMU8000_PEFE_WRITE(hw, ch, vp->reg.parm.pefe);
 270
 271        /* lfo1/2 delay */
 272        EMU8000_LFO1VAL_WRITE(hw, ch, vp->reg.parm.lfo1delay);
 273        EMU8000_LFO2VAL_WRITE(hw, ch, vp->reg.parm.lfo2delay);
 274
 275        /* lfo1 pitch & cutoff shift */
 276        set_fmmod(hw, vp);
 277        /* lfo1 volume & freq */
 278        set_tremfreq(hw, vp);
 279        /* lfo2 pitch & freq */
 280        set_fm2frq2(hw, vp);
 281        /* pan & loop start */
 282        set_pan(hw, vp);
 283
 284        /* chorus & loop end (chorus 8bit, MSB) */
 285        addr = vp->reg.loopend - 1;
 286        temp = vp->reg.parm.chorus;
 287        temp += (int)chan->control[MIDI_CTL_E3_CHORUS_DEPTH] * 9 / 10;
 288        LIMITMAX(temp, 255);
 289        temp = (temp <<24) | (unsigned int)addr;
 290        EMU8000_CSL_WRITE(hw, ch, temp);
 291
 292        /* Q & current address (Q 4bit value, MSB) */
 293        addr = vp->reg.start - 1;
 294        temp = vp->reg.parm.filterQ;
 295        temp = (temp<<28) | (unsigned int)addr;
 296        EMU8000_CCCA_WRITE(hw, ch, temp);
 297
 298        /* clear unknown registers */
 299        EMU8000_00A0_WRITE(hw, ch, 0);
 300        EMU8000_0080_WRITE(hw, ch, 0);
 301
 302        /* reset volume */
 303        temp = vp->vtarget << 16;
 304        EMU8000_VTFT_WRITE(hw, ch, temp | vp->ftarget);
 305        EMU8000_CVCF_WRITE(hw, ch, temp | 0xff00);
 306
 307        return 0;
 308}
 309
 310/*
 311 * Start envelope
 312 */
 313static void
 314trigger_voice(struct snd_emux_voice *vp)
 315{
 316        int ch = vp->ch;
 317        unsigned int temp;
 318        struct snd_emu8000 *hw;
 319
 320        hw = vp->hw;
 321
 322        /* set reverb and pitch target */
 323        temp = vp->reg.parm.reverb;
 324        temp += (int)vp->chan->control[MIDI_CTL_E1_REVERB_DEPTH] * 9 / 10;
 325        LIMITMAX(temp, 255);
 326        temp = (temp << 8) | (vp->ptarget << 16) | vp->aaux;
 327        EMU8000_PTRX_WRITE(hw, ch, temp);
 328        EMU8000_CPF_WRITE(hw, ch, vp->ptarget << 16);
 329        EMU8000_DCYSUSV_WRITE(hw, ch, vp->reg.parm.voldcysus);
 330}
 331
 332/*
 333 * reset voice parameters
 334 */
 335static void
 336reset_voice(struct snd_emux *emu, int ch)
 337{
 338        struct snd_emu8000 *hw;
 339
 340        hw = emu->hw;
 341        EMU8000_DCYSUSV_WRITE(hw, ch, 0x807F);
 342        snd_emu8000_tweak_voice(hw, ch);
 343}
 344
 345/*
 346 * Set the pitch of a possibly playing note.
 347 */
 348static void
 349set_pitch(struct snd_emu8000 *hw, struct snd_emux_voice *vp)
 350{
 351        EMU8000_IP_WRITE(hw, vp->ch, vp->apitch);
 352}
 353
 354/*
 355 * Set the volume of a possibly already playing note
 356 */
 357static void
 358set_volume(struct snd_emu8000 *hw, struct snd_emux_voice *vp)
 359{
 360        int  ifatn;
 361
 362        ifatn = (unsigned char)vp->acutoff;
 363        ifatn = (ifatn << 8);
 364        ifatn |= (unsigned char)vp->avol;
 365        EMU8000_IFATN_WRITE(hw, vp->ch, ifatn);
 366}
 367
 368/*
 369 * Set pan and loop start address.
 370 */
 371static void
 372set_pan(struct snd_emu8000 *hw, struct snd_emux_voice *vp)
 373{
 374        unsigned int temp;
 375
 376        temp = ((unsigned int)vp->apan<<24) | ((unsigned int)vp->reg.loopstart - 1);
 377        EMU8000_PSST_WRITE(hw, vp->ch, temp);
 378}
 379
 380#define MOD_SENSE 18
 381
 382static void
 383set_fmmod(struct snd_emu8000 *hw, struct snd_emux_voice *vp)
 384{
 385        unsigned short fmmod;
 386        short pitch;
 387        unsigned char cutoff;
 388        int modulation;
 389
 390        pitch = (char)(vp->reg.parm.fmmod>>8);
 391        cutoff = (vp->reg.parm.fmmod & 0xff);
 392        modulation = vp->chan->gm_modulation + vp->chan->midi_pressure;
 393        pitch += (MOD_SENSE * modulation) / 1200;
 394        LIMITVALUE(pitch, -128, 127);
 395        fmmod = ((unsigned char)pitch<<8) | cutoff;
 396        EMU8000_FMMOD_WRITE(hw, vp->ch, fmmod);
 397}
 398
 399/* set tremolo (lfo1) volume & frequency */
 400static void
 401set_tremfreq(struct snd_emu8000 *hw, struct snd_emux_voice *vp)
 402{
 403        EMU8000_TREMFRQ_WRITE(hw, vp->ch, vp->reg.parm.tremfrq);
 404}
 405
 406/* set lfo2 pitch & frequency */
 407static void
 408set_fm2frq2(struct snd_emu8000 *hw, struct snd_emux_voice *vp)
 409{
 410        unsigned short fm2frq2;
 411        short pitch;
 412        unsigned char freq;
 413        int modulation;
 414
 415        pitch = (char)(vp->reg.parm.fm2frq2>>8);
 416        freq = vp->reg.parm.fm2frq2 & 0xff;
 417        modulation = vp->chan->gm_modulation + vp->chan->midi_pressure;
 418        pitch += (MOD_SENSE * modulation) / 1200;
 419        LIMITVALUE(pitch, -128, 127);
 420        fm2frq2 = ((unsigned char)pitch<<8) | freq;
 421        EMU8000_FM2FRQ2_WRITE(hw, vp->ch, fm2frq2);
 422}
 423
 424/* set filterQ */
 425static void
 426set_filterQ(struct snd_emu8000 *hw, struct snd_emux_voice *vp)
 427{
 428        unsigned int addr;
 429        addr = EMU8000_CCCA_READ(hw, vp->ch) & 0xffffff;
 430        addr |= (vp->reg.parm.filterQ << 28);
 431        EMU8000_CCCA_WRITE(hw, vp->ch, addr);
 432}
 433
 434/*
 435 * set the envelope & LFO parameters to the default values
 436 */
 437static void
 438snd_emu8000_tweak_voice(struct snd_emu8000 *emu, int i)
 439{
 440        /* set all mod/vol envelope shape to minimum */
 441        EMU8000_ENVVOL_WRITE(emu, i, 0x8000);
 442        EMU8000_ENVVAL_WRITE(emu, i, 0x8000);
 443        EMU8000_DCYSUS_WRITE(emu, i, 0x7F7F);
 444        EMU8000_ATKHLDV_WRITE(emu, i, 0x7F7F);
 445        EMU8000_ATKHLD_WRITE(emu, i, 0x7F7F);
 446        EMU8000_PEFE_WRITE(emu, i, 0);  /* mod envelope height to zero */
 447        EMU8000_LFO1VAL_WRITE(emu, i, 0x8000); /* no delay for LFO1 */
 448        EMU8000_LFO2VAL_WRITE(emu, i, 0x8000);
 449        EMU8000_IP_WRITE(emu, i, 0xE000);       /* no pitch shift */
 450        EMU8000_IFATN_WRITE(emu, i, 0xFF00);    /* volume to minimum */
 451        EMU8000_FMMOD_WRITE(emu, i, 0);
 452        EMU8000_TREMFRQ_WRITE(emu, i, 0);
 453        EMU8000_FM2FRQ2_WRITE(emu, i, 0);
 454}
 455
 456/*
 457 * sysex callback
 458 */
 459static void
 460sysex(struct snd_emux *emu, char *buf, int len, int parsed, struct snd_midi_channel_set *chset)
 461{
 462        struct snd_emu8000 *hw;
 463
 464        hw = emu->hw;
 465
 466        switch (parsed) {
 467        case SNDRV_MIDI_SYSEX_GS_CHORUS_MODE:
 468                hw->chorus_mode = chset->gs_chorus_mode;
 469                snd_emu8000_update_chorus_mode(hw);
 470                break;
 471
 472        case SNDRV_MIDI_SYSEX_GS_REVERB_MODE:
 473                hw->reverb_mode = chset->gs_reverb_mode;
 474                snd_emu8000_update_reverb_mode(hw);
 475                break;
 476        }
 477}
 478
 479
 480#if IS_ENABLED(CONFIG_SND_SEQUENCER_OSS)
 481/*
 482 * OSS ioctl callback
 483 */
 484static int
 485oss_ioctl(struct snd_emux *emu, int cmd, int p1, int p2)
 486{
 487        struct snd_emu8000 *hw;
 488
 489        hw = emu->hw;
 490
 491        switch (cmd) {
 492        case _EMUX_OSS_REVERB_MODE:
 493                hw->reverb_mode = p1;
 494                snd_emu8000_update_reverb_mode(hw);
 495                break;
 496
 497        case _EMUX_OSS_CHORUS_MODE:
 498                hw->chorus_mode = p1;
 499                snd_emu8000_update_chorus_mode(hw);
 500                break;
 501
 502        case _EMUX_OSS_INITIALIZE_CHIP:
 503                /* snd_emu8000_init(hw); */ /*ignored*/
 504                break;
 505
 506        case _EMUX_OSS_EQUALIZER:
 507                hw->bass_level = p1;
 508                hw->treble_level = p2;
 509                snd_emu8000_update_equalizer(hw);
 510                break;
 511        }
 512        return 0;
 513}
 514#endif
 515
 516
 517/*
 518 * additional patch keys
 519 */
 520
 521#define SNDRV_EMU8000_LOAD_CHORUS_FX    0x10    /* optarg=mode */
 522#define SNDRV_EMU8000_LOAD_REVERB_FX    0x11    /* optarg=mode */
 523
 524
 525/*
 526 * callback routine
 527 */
 528
 529static int
 530load_fx(struct snd_emux *emu, int type, int mode, const void __user *buf, long len)
 531{
 532        struct snd_emu8000 *hw;
 533        hw = emu->hw;
 534
 535        /* skip header */
 536        buf += 16;
 537        len -= 16;
 538
 539        switch (type) {
 540        case SNDRV_EMU8000_LOAD_CHORUS_FX:
 541                return snd_emu8000_load_chorus_fx(hw, mode, buf, len);
 542        case SNDRV_EMU8000_LOAD_REVERB_FX:
 543                return snd_emu8000_load_reverb_fx(hw, mode, buf, len);
 544        }
 545        return -EINVAL;
 546}
 547
 548