linux/sound/drivers/opl4/opl4_synth.c
<<
>>
Prefs
   1/*
   2 * OPL4 MIDI synthesizer functions
   3 *
   4 * Copyright (c) 2003 by Clemens Ladisch <clemens@ladisch.de>
   5 * All rights reserved.
   6 *
   7 * Redistribution and use in source and binary forms, with or without
   8 * modification, are permitted provided that the following conditions
   9 * are met:
  10 * 1. Redistributions of source code must retain the above copyright
  11 *    notice, this list of conditions, and the following disclaimer,
  12 *    without modification.
  13 * 2. The name of the author may not be used to endorse or promote products
  14 *    derived from this software without specific prior written permission.
  15 *
  16 * Alternatively, this software may be distributed and/or modified under the
  17 * terms of the GNU General Public License as published by the Free Software
  18 * Foundation; either version 2 of the License, or (at your option) any later
  19 * version.
  20 *
  21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
  25 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31 * SUCH DAMAGE.
  32 */
  33
  34#include "opl4_local.h"
  35#include <linux/delay.h>
  36#include <asm/io.h>
  37#include <sound/asoundef.h>
  38
  39/* GM2 controllers */
  40#ifndef MIDI_CTL_RELEASE_TIME
  41#define MIDI_CTL_RELEASE_TIME   0x48
  42#define MIDI_CTL_ATTACK_TIME    0x49
  43#define MIDI_CTL_DECAY_TIME     0x4b
  44#define MIDI_CTL_VIBRATO_RATE   0x4c
  45#define MIDI_CTL_VIBRATO_DEPTH  0x4d
  46#define MIDI_CTL_VIBRATO_DELAY  0x4e
  47#endif
  48
  49/*
  50 * This table maps 100/128 cents to F_NUMBER.
  51 */
  52static const s16 snd_opl4_pitch_map[0x600] = {
  53        0x000,0x000,0x001,0x001,0x002,0x002,0x003,0x003,
  54        0x004,0x004,0x005,0x005,0x006,0x006,0x006,0x007,
  55        0x007,0x008,0x008,0x009,0x009,0x00a,0x00a,0x00b,
  56        0x00b,0x00c,0x00c,0x00d,0x00d,0x00d,0x00e,0x00e,
  57        0x00f,0x00f,0x010,0x010,0x011,0x011,0x012,0x012,
  58        0x013,0x013,0x014,0x014,0x015,0x015,0x015,0x016,
  59        0x016,0x017,0x017,0x018,0x018,0x019,0x019,0x01a,
  60        0x01a,0x01b,0x01b,0x01c,0x01c,0x01d,0x01d,0x01e,
  61        0x01e,0x01e,0x01f,0x01f,0x020,0x020,0x021,0x021,
  62        0x022,0x022,0x023,0x023,0x024,0x024,0x025,0x025,
  63        0x026,0x026,0x027,0x027,0x028,0x028,0x029,0x029,
  64        0x029,0x02a,0x02a,0x02b,0x02b,0x02c,0x02c,0x02d,
  65        0x02d,0x02e,0x02e,0x02f,0x02f,0x030,0x030,0x031,
  66        0x031,0x032,0x032,0x033,0x033,0x034,0x034,0x035,
  67        0x035,0x036,0x036,0x037,0x037,0x038,0x038,0x038,
  68        0x039,0x039,0x03a,0x03a,0x03b,0x03b,0x03c,0x03c,
  69        0x03d,0x03d,0x03e,0x03e,0x03f,0x03f,0x040,0x040,
  70        0x041,0x041,0x042,0x042,0x043,0x043,0x044,0x044,
  71        0x045,0x045,0x046,0x046,0x047,0x047,0x048,0x048,
  72        0x049,0x049,0x04a,0x04a,0x04b,0x04b,0x04c,0x04c,
  73        0x04d,0x04d,0x04e,0x04e,0x04f,0x04f,0x050,0x050,
  74        0x051,0x051,0x052,0x052,0x053,0x053,0x054,0x054,
  75        0x055,0x055,0x056,0x056,0x057,0x057,0x058,0x058,
  76        0x059,0x059,0x05a,0x05a,0x05b,0x05b,0x05c,0x05c,
  77        0x05d,0x05d,0x05e,0x05e,0x05f,0x05f,0x060,0x060,
  78        0x061,0x061,0x062,0x062,0x063,0x063,0x064,0x064,
  79        0x065,0x065,0x066,0x066,0x067,0x067,0x068,0x068,
  80        0x069,0x069,0x06a,0x06a,0x06b,0x06b,0x06c,0x06c,
  81        0x06d,0x06d,0x06e,0x06e,0x06f,0x06f,0x070,0x071,
  82        0x071,0x072,0x072,0x073,0x073,0x074,0x074,0x075,
  83        0x075,0x076,0x076,0x077,0x077,0x078,0x078,0x079,
  84        0x079,0x07a,0x07a,0x07b,0x07b,0x07c,0x07c,0x07d,
  85        0x07d,0x07e,0x07e,0x07f,0x07f,0x080,0x081,0x081,
  86        0x082,0x082,0x083,0x083,0x084,0x084,0x085,0x085,
  87        0x086,0x086,0x087,0x087,0x088,0x088,0x089,0x089,
  88        0x08a,0x08a,0x08b,0x08b,0x08c,0x08d,0x08d,0x08e,
  89        0x08e,0x08f,0x08f,0x090,0x090,0x091,0x091,0x092,
  90        0x092,0x093,0x093,0x094,0x094,0x095,0x096,0x096,
  91        0x097,0x097,0x098,0x098,0x099,0x099,0x09a,0x09a,
  92        0x09b,0x09b,0x09c,0x09c,0x09d,0x09d,0x09e,0x09f,
  93        0x09f,0x0a0,0x0a0,0x0a1,0x0a1,0x0a2,0x0a2,0x0a3,
  94        0x0a3,0x0a4,0x0a4,0x0a5,0x0a6,0x0a6,0x0a7,0x0a7,
  95        0x0a8,0x0a8,0x0a9,0x0a9,0x0aa,0x0aa,0x0ab,0x0ab,
  96        0x0ac,0x0ad,0x0ad,0x0ae,0x0ae,0x0af,0x0af,0x0b0,
  97        0x0b0,0x0b1,0x0b1,0x0b2,0x0b2,0x0b3,0x0b4,0x0b4,
  98        0x0b5,0x0b5,0x0b6,0x0b6,0x0b7,0x0b7,0x0b8,0x0b8,
  99        0x0b9,0x0ba,0x0ba,0x0bb,0x0bb,0x0bc,0x0bc,0x0bd,
 100        0x0bd,0x0be,0x0be,0x0bf,0x0c0,0x0c0,0x0c1,0x0c1,
 101        0x0c2,0x0c2,0x0c3,0x0c3,0x0c4,0x0c4,0x0c5,0x0c6,
 102        0x0c6,0x0c7,0x0c7,0x0c8,0x0c8,0x0c9,0x0c9,0x0ca,
 103        0x0cb,0x0cb,0x0cc,0x0cc,0x0cd,0x0cd,0x0ce,0x0ce,
 104        0x0cf,0x0d0,0x0d0,0x0d1,0x0d1,0x0d2,0x0d2,0x0d3,
 105        0x0d3,0x0d4,0x0d5,0x0d5,0x0d6,0x0d6,0x0d7,0x0d7,
 106        0x0d8,0x0d8,0x0d9,0x0da,0x0da,0x0db,0x0db,0x0dc,
 107        0x0dc,0x0dd,0x0de,0x0de,0x0df,0x0df,0x0e0,0x0e0,
 108        0x0e1,0x0e1,0x0e2,0x0e3,0x0e3,0x0e4,0x0e4,0x0e5,
 109        0x0e5,0x0e6,0x0e7,0x0e7,0x0e8,0x0e8,0x0e9,0x0e9,
 110        0x0ea,0x0eb,0x0eb,0x0ec,0x0ec,0x0ed,0x0ed,0x0ee,
 111        0x0ef,0x0ef,0x0f0,0x0f0,0x0f1,0x0f1,0x0f2,0x0f3,
 112        0x0f3,0x0f4,0x0f4,0x0f5,0x0f5,0x0f6,0x0f7,0x0f7,
 113        0x0f8,0x0f8,0x0f9,0x0f9,0x0fa,0x0fb,0x0fb,0x0fc,
 114        0x0fc,0x0fd,0x0fd,0x0fe,0x0ff,0x0ff,0x100,0x100,
 115        0x101,0x101,0x102,0x103,0x103,0x104,0x104,0x105,
 116        0x106,0x106,0x107,0x107,0x108,0x108,0x109,0x10a,
 117        0x10a,0x10b,0x10b,0x10c,0x10c,0x10d,0x10e,0x10e,
 118        0x10f,0x10f,0x110,0x111,0x111,0x112,0x112,0x113,
 119        0x114,0x114,0x115,0x115,0x116,0x116,0x117,0x118,
 120        0x118,0x119,0x119,0x11a,0x11b,0x11b,0x11c,0x11c,
 121        0x11d,0x11e,0x11e,0x11f,0x11f,0x120,0x120,0x121,
 122        0x122,0x122,0x123,0x123,0x124,0x125,0x125,0x126,
 123        0x126,0x127,0x128,0x128,0x129,0x129,0x12a,0x12b,
 124        0x12b,0x12c,0x12c,0x12d,0x12e,0x12e,0x12f,0x12f,
 125        0x130,0x131,0x131,0x132,0x132,0x133,0x134,0x134,
 126        0x135,0x135,0x136,0x137,0x137,0x138,0x138,0x139,
 127        0x13a,0x13a,0x13b,0x13b,0x13c,0x13d,0x13d,0x13e,
 128        0x13e,0x13f,0x140,0x140,0x141,0x141,0x142,0x143,
 129        0x143,0x144,0x144,0x145,0x146,0x146,0x147,0x148,
 130        0x148,0x149,0x149,0x14a,0x14b,0x14b,0x14c,0x14c,
 131        0x14d,0x14e,0x14e,0x14f,0x14f,0x150,0x151,0x151,
 132        0x152,0x153,0x153,0x154,0x154,0x155,0x156,0x156,
 133        0x157,0x157,0x158,0x159,0x159,0x15a,0x15b,0x15b,
 134        0x15c,0x15c,0x15d,0x15e,0x15e,0x15f,0x160,0x160,
 135        0x161,0x161,0x162,0x163,0x163,0x164,0x165,0x165,
 136        0x166,0x166,0x167,0x168,0x168,0x169,0x16a,0x16a,
 137        0x16b,0x16b,0x16c,0x16d,0x16d,0x16e,0x16f,0x16f,
 138        0x170,0x170,0x171,0x172,0x172,0x173,0x174,0x174,
 139        0x175,0x175,0x176,0x177,0x177,0x178,0x179,0x179,
 140        0x17a,0x17a,0x17b,0x17c,0x17c,0x17d,0x17e,0x17e,
 141        0x17f,0x180,0x180,0x181,0x181,0x182,0x183,0x183,
 142        0x184,0x185,0x185,0x186,0x187,0x187,0x188,0x188,
 143        0x189,0x18a,0x18a,0x18b,0x18c,0x18c,0x18d,0x18e,
 144        0x18e,0x18f,0x190,0x190,0x191,0x191,0x192,0x193,
 145        0x193,0x194,0x195,0x195,0x196,0x197,0x197,0x198,
 146        0x199,0x199,0x19a,0x19a,0x19b,0x19c,0x19c,0x19d,
 147        0x19e,0x19e,0x19f,0x1a0,0x1a0,0x1a1,0x1a2,0x1a2,
 148        0x1a3,0x1a4,0x1a4,0x1a5,0x1a6,0x1a6,0x1a7,0x1a8,
 149        0x1a8,0x1a9,0x1a9,0x1aa,0x1ab,0x1ab,0x1ac,0x1ad,
 150        0x1ad,0x1ae,0x1af,0x1af,0x1b0,0x1b1,0x1b1,0x1b2,
 151        0x1b3,0x1b3,0x1b4,0x1b5,0x1b5,0x1b6,0x1b7,0x1b7,
 152        0x1b8,0x1b9,0x1b9,0x1ba,0x1bb,0x1bb,0x1bc,0x1bd,
 153        0x1bd,0x1be,0x1bf,0x1bf,0x1c0,0x1c1,0x1c1,0x1c2,
 154        0x1c3,0x1c3,0x1c4,0x1c5,0x1c5,0x1c6,0x1c7,0x1c7,
 155        0x1c8,0x1c9,0x1c9,0x1ca,0x1cb,0x1cb,0x1cc,0x1cd,
 156        0x1cd,0x1ce,0x1cf,0x1cf,0x1d0,0x1d1,0x1d1,0x1d2,
 157        0x1d3,0x1d3,0x1d4,0x1d5,0x1d5,0x1d6,0x1d7,0x1d7,
 158        0x1d8,0x1d9,0x1d9,0x1da,0x1db,0x1db,0x1dc,0x1dd,
 159        0x1dd,0x1de,0x1df,0x1df,0x1e0,0x1e1,0x1e1,0x1e2,
 160        0x1e3,0x1e4,0x1e4,0x1e5,0x1e6,0x1e6,0x1e7,0x1e8,
 161        0x1e8,0x1e9,0x1ea,0x1ea,0x1eb,0x1ec,0x1ec,0x1ed,
 162        0x1ee,0x1ee,0x1ef,0x1f0,0x1f0,0x1f1,0x1f2,0x1f3,
 163        0x1f3,0x1f4,0x1f5,0x1f5,0x1f6,0x1f7,0x1f7,0x1f8,
 164        0x1f9,0x1f9,0x1fa,0x1fb,0x1fb,0x1fc,0x1fd,0x1fe,
 165        0x1fe,0x1ff,0x200,0x200,0x201,0x202,0x202,0x203,
 166        0x204,0x205,0x205,0x206,0x207,0x207,0x208,0x209,
 167        0x209,0x20a,0x20b,0x20b,0x20c,0x20d,0x20e,0x20e,
 168        0x20f,0x210,0x210,0x211,0x212,0x212,0x213,0x214,
 169        0x215,0x215,0x216,0x217,0x217,0x218,0x219,0x21a,
 170        0x21a,0x21b,0x21c,0x21c,0x21d,0x21e,0x21e,0x21f,
 171        0x220,0x221,0x221,0x222,0x223,0x223,0x224,0x225,
 172        0x226,0x226,0x227,0x228,0x228,0x229,0x22a,0x22b,
 173        0x22b,0x22c,0x22d,0x22d,0x22e,0x22f,0x230,0x230,
 174        0x231,0x232,0x232,0x233,0x234,0x235,0x235,0x236,
 175        0x237,0x237,0x238,0x239,0x23a,0x23a,0x23b,0x23c,
 176        0x23c,0x23d,0x23e,0x23f,0x23f,0x240,0x241,0x241,
 177        0x242,0x243,0x244,0x244,0x245,0x246,0x247,0x247,
 178        0x248,0x249,0x249,0x24a,0x24b,0x24c,0x24c,0x24d,
 179        0x24e,0x24f,0x24f,0x250,0x251,0x251,0x252,0x253,
 180        0x254,0x254,0x255,0x256,0x257,0x257,0x258,0x259,
 181        0x259,0x25a,0x25b,0x25c,0x25c,0x25d,0x25e,0x25f,
 182        0x25f,0x260,0x261,0x262,0x262,0x263,0x264,0x265,
 183        0x265,0x266,0x267,0x267,0x268,0x269,0x26a,0x26a,
 184        0x26b,0x26c,0x26d,0x26d,0x26e,0x26f,0x270,0x270,
 185        0x271,0x272,0x273,0x273,0x274,0x275,0x276,0x276,
 186        0x277,0x278,0x279,0x279,0x27a,0x27b,0x27c,0x27c,
 187        0x27d,0x27e,0x27f,0x27f,0x280,0x281,0x282,0x282,
 188        0x283,0x284,0x285,0x285,0x286,0x287,0x288,0x288,
 189        0x289,0x28a,0x28b,0x28b,0x28c,0x28d,0x28e,0x28e,
 190        0x28f,0x290,0x291,0x291,0x292,0x293,0x294,0x294,
 191        0x295,0x296,0x297,0x298,0x298,0x299,0x29a,0x29b,
 192        0x29b,0x29c,0x29d,0x29e,0x29e,0x29f,0x2a0,0x2a1,
 193        0x2a1,0x2a2,0x2a3,0x2a4,0x2a5,0x2a5,0x2a6,0x2a7,
 194        0x2a8,0x2a8,0x2a9,0x2aa,0x2ab,0x2ab,0x2ac,0x2ad,
 195        0x2ae,0x2af,0x2af,0x2b0,0x2b1,0x2b2,0x2b2,0x2b3,
 196        0x2b4,0x2b5,0x2b5,0x2b6,0x2b7,0x2b8,0x2b9,0x2b9,
 197        0x2ba,0x2bb,0x2bc,0x2bc,0x2bd,0x2be,0x2bf,0x2c0,
 198        0x2c0,0x2c1,0x2c2,0x2c3,0x2c4,0x2c4,0x2c5,0x2c6,
 199        0x2c7,0x2c7,0x2c8,0x2c9,0x2ca,0x2cb,0x2cb,0x2cc,
 200        0x2cd,0x2ce,0x2ce,0x2cf,0x2d0,0x2d1,0x2d2,0x2d2,
 201        0x2d3,0x2d4,0x2d5,0x2d6,0x2d6,0x2d7,0x2d8,0x2d9,
 202        0x2da,0x2da,0x2db,0x2dc,0x2dd,0x2dd,0x2de,0x2df,
 203        0x2e0,0x2e1,0x2e1,0x2e2,0x2e3,0x2e4,0x2e5,0x2e5,
 204        0x2e6,0x2e7,0x2e8,0x2e9,0x2e9,0x2ea,0x2eb,0x2ec,
 205        0x2ed,0x2ed,0x2ee,0x2ef,0x2f0,0x2f1,0x2f1,0x2f2,
 206        0x2f3,0x2f4,0x2f5,0x2f5,0x2f6,0x2f7,0x2f8,0x2f9,
 207        0x2f9,0x2fa,0x2fb,0x2fc,0x2fd,0x2fd,0x2fe,0x2ff,
 208        0x300,0x301,0x302,0x302,0x303,0x304,0x305,0x306,
 209        0x306,0x307,0x308,0x309,0x30a,0x30a,0x30b,0x30c,
 210        0x30d,0x30e,0x30f,0x30f,0x310,0x311,0x312,0x313,
 211        0x313,0x314,0x315,0x316,0x317,0x318,0x318,0x319,
 212        0x31a,0x31b,0x31c,0x31c,0x31d,0x31e,0x31f,0x320,
 213        0x321,0x321,0x322,0x323,0x324,0x325,0x326,0x326,
 214        0x327,0x328,0x329,0x32a,0x32a,0x32b,0x32c,0x32d,
 215        0x32e,0x32f,0x32f,0x330,0x331,0x332,0x333,0x334,
 216        0x334,0x335,0x336,0x337,0x338,0x339,0x339,0x33a,
 217        0x33b,0x33c,0x33d,0x33e,0x33e,0x33f,0x340,0x341,
 218        0x342,0x343,0x343,0x344,0x345,0x346,0x347,0x348,
 219        0x349,0x349,0x34a,0x34b,0x34c,0x34d,0x34e,0x34e,
 220        0x34f,0x350,0x351,0x352,0x353,0x353,0x354,0x355,
 221        0x356,0x357,0x358,0x359,0x359,0x35a,0x35b,0x35c,
 222        0x35d,0x35e,0x35f,0x35f,0x360,0x361,0x362,0x363,
 223        0x364,0x364,0x365,0x366,0x367,0x368,0x369,0x36a,
 224        0x36a,0x36b,0x36c,0x36d,0x36e,0x36f,0x370,0x370,
 225        0x371,0x372,0x373,0x374,0x375,0x376,0x377,0x377,
 226        0x378,0x379,0x37a,0x37b,0x37c,0x37d,0x37d,0x37e,
 227        0x37f,0x380,0x381,0x382,0x383,0x383,0x384,0x385,
 228        0x386,0x387,0x388,0x389,0x38a,0x38a,0x38b,0x38c,
 229        0x38d,0x38e,0x38f,0x390,0x391,0x391,0x392,0x393,
 230        0x394,0x395,0x396,0x397,0x398,0x398,0x399,0x39a,
 231        0x39b,0x39c,0x39d,0x39e,0x39f,0x39f,0x3a0,0x3a1,
 232        0x3a2,0x3a3,0x3a4,0x3a5,0x3a6,0x3a7,0x3a7,0x3a8,
 233        0x3a9,0x3aa,0x3ab,0x3ac,0x3ad,0x3ae,0x3ae,0x3af,
 234        0x3b0,0x3b1,0x3b2,0x3b3,0x3b4,0x3b5,0x3b6,0x3b6,
 235        0x3b7,0x3b8,0x3b9,0x3ba,0x3bb,0x3bc,0x3bd,0x3be,
 236        0x3bf,0x3bf,0x3c0,0x3c1,0x3c2,0x3c3,0x3c4,0x3c5,
 237        0x3c6,0x3c7,0x3c7,0x3c8,0x3c9,0x3ca,0x3cb,0x3cc,
 238        0x3cd,0x3ce,0x3cf,0x3d0,0x3d1,0x3d1,0x3d2,0x3d3,
 239        0x3d4,0x3d5,0x3d6,0x3d7,0x3d8,0x3d9,0x3da,0x3da,
 240        0x3db,0x3dc,0x3dd,0x3de,0x3df,0x3e0,0x3e1,0x3e2,
 241        0x3e3,0x3e4,0x3e4,0x3e5,0x3e6,0x3e7,0x3e8,0x3e9,
 242        0x3ea,0x3eb,0x3ec,0x3ed,0x3ee,0x3ef,0x3ef,0x3f0,
 243        0x3f1,0x3f2,0x3f3,0x3f4,0x3f5,0x3f6,0x3f7,0x3f8,
 244        0x3f9,0x3fa,0x3fa,0x3fb,0x3fc,0x3fd,0x3fe,0x3ff
 245};
 246
 247/*
 248 * Attenuation according to GM recommendations, in -0.375 dB units.
 249 * table[v] = 40 * log(v / 127) / -0.375
 250 */
 251static unsigned char snd_opl4_volume_table[128] = {
 252        255,224,192,173,160,150,141,134,
 253        128,122,117,113,109,105,102, 99,
 254         96, 93, 90, 88, 85, 83, 81, 79,
 255         77, 75, 73, 71, 70, 68, 67, 65,
 256         64, 62, 61, 59, 58, 57, 56, 54,
 257         53, 52, 51, 50, 49, 48, 47, 46,
 258         45, 44, 43, 42, 41, 40, 39, 39,
 259         38, 37, 36, 35, 34, 34, 33, 32,
 260         31, 31, 30, 29, 29, 28, 27, 27,
 261         26, 25, 25, 24, 24, 23, 22, 22,
 262         21, 21, 20, 19, 19, 18, 18, 17,
 263         17, 16, 16, 15, 15, 14, 14, 13,
 264         13, 12, 12, 11, 11, 10, 10,  9,
 265          9,  9,  8,  8,  7,  7,  6,  6,
 266          6,  5,  5,  4,  4,  4,  3,  3,
 267          2,  2,  2,  1,  1,  0,  0,  0
 268};
 269
 270/*
 271 * Initializes all voices.
 272 */
 273void snd_opl4_synth_reset(struct snd_opl4 *opl4)
 274{
 275        unsigned long flags;
 276        int i;
 277
 278        spin_lock_irqsave(&opl4->reg_lock, flags);
 279        for (i = 0; i < OPL4_MAX_VOICES; i++)
 280                snd_opl4_write(opl4, OPL4_REG_MISC + i, OPL4_DAMP_BIT);
 281        spin_unlock_irqrestore(&opl4->reg_lock, flags);
 282
 283        INIT_LIST_HEAD(&opl4->off_voices);
 284        INIT_LIST_HEAD(&opl4->on_voices);
 285        memset(opl4->voices, 0, sizeof(opl4->voices));
 286        for (i = 0; i < OPL4_MAX_VOICES; i++) {
 287                opl4->voices[i].number = i;
 288                list_add_tail(&opl4->voices[i].list, &opl4->off_voices);
 289        }
 290
 291        snd_midi_channel_set_clear(opl4->chset);
 292}
 293
 294/*
 295 * Shuts down all voices.
 296 */
 297void snd_opl4_synth_shutdown(struct snd_opl4 *opl4)
 298{
 299        unsigned long flags;
 300        int i;
 301
 302        spin_lock_irqsave(&opl4->reg_lock, flags);
 303        for (i = 0; i < OPL4_MAX_VOICES; i++)
 304                snd_opl4_write(opl4, OPL4_REG_MISC + i,
 305                               opl4->voices[i].reg_misc & ~OPL4_KEY_ON_BIT);
 306        spin_unlock_irqrestore(&opl4->reg_lock, flags);
 307}
 308
 309/*
 310 * Executes the callback for all voices playing the specified note.
 311 */
 312static void snd_opl4_do_for_note(struct snd_opl4 *opl4, int note, struct snd_midi_channel *chan,
 313                                 void (*func)(struct snd_opl4 *opl4, struct opl4_voice *voice))
 314{
 315        int i;
 316        unsigned long flags;
 317        struct opl4_voice *voice;
 318
 319        spin_lock_irqsave(&opl4->reg_lock, flags);
 320        for (i = 0; i < OPL4_MAX_VOICES; i++) {
 321                voice = &opl4->voices[i];
 322                if (voice->chan == chan && voice->note == note) {
 323                        func(opl4, voice);
 324                }
 325        }
 326        spin_unlock_irqrestore(&opl4->reg_lock, flags);
 327}
 328
 329/*
 330 * Executes the callback for all voices of to the specified channel.
 331 */
 332static void snd_opl4_do_for_channel(struct snd_opl4 *opl4,
 333                                    struct snd_midi_channel *chan,
 334                                    void (*func)(struct snd_opl4 *opl4, struct opl4_voice *voice))
 335{
 336        int i;
 337        unsigned long flags;
 338        struct opl4_voice *voice;
 339
 340        spin_lock_irqsave(&opl4->reg_lock, flags);
 341        for (i = 0; i < OPL4_MAX_VOICES; i++) {
 342                voice = &opl4->voices[i];
 343                if (voice->chan == chan) {
 344                        func(opl4, voice);
 345                }
 346        }
 347        spin_unlock_irqrestore(&opl4->reg_lock, flags);
 348}
 349
 350/*
 351 * Executes the callback for all active voices.
 352 */
 353static void snd_opl4_do_for_all(struct snd_opl4 *opl4,
 354                                void (*func)(struct snd_opl4 *opl4, struct opl4_voice *voice))
 355{
 356        int i;
 357        unsigned long flags;
 358        struct opl4_voice *voice;
 359
 360        spin_lock_irqsave(&opl4->reg_lock, flags);
 361        for (i = 0; i < OPL4_MAX_VOICES; i++) {
 362                voice = &opl4->voices[i];
 363                if (voice->chan)
 364                        func(opl4, voice);
 365        }
 366        spin_unlock_irqrestore(&opl4->reg_lock, flags);
 367}
 368
 369static void snd_opl4_update_volume(struct snd_opl4 *opl4, struct opl4_voice *voice)
 370{
 371        int att;
 372
 373        att = voice->sound->tone_attenuate;
 374        att += snd_opl4_volume_table[opl4->chset->gs_master_volume & 0x7f];
 375        att += snd_opl4_volume_table[voice->chan->gm_volume & 0x7f];
 376        att += snd_opl4_volume_table[voice->chan->gm_expression & 0x7f];
 377        att += snd_opl4_volume_table[voice->velocity];
 378        att = 0x7f - (0x7f - att) * (voice->sound->volume_factor) / 0xfe - volume_boost;
 379        if (att < 0)
 380                att = 0;
 381        else if (att > 0x7e)
 382                att = 0x7e;
 383        snd_opl4_write(opl4, OPL4_REG_LEVEL + voice->number,
 384                       (att << 1) | voice->level_direct);
 385        voice->level_direct = 0;
 386}
 387
 388static void snd_opl4_update_pan(struct snd_opl4 *opl4, struct opl4_voice *voice)
 389{
 390        int pan = voice->sound->panpot;
 391
 392        if (!voice->chan->drum_channel)
 393                pan += (voice->chan->control[MIDI_CTL_MSB_PAN] - 0x40) >> 3;
 394        if (pan < -7)
 395                pan = -7;
 396        else if (pan > 7)
 397                pan = 7;
 398        voice->reg_misc = (voice->reg_misc & ~OPL4_PAN_POT_MASK)
 399                | (pan & OPL4_PAN_POT_MASK);
 400        snd_opl4_write(opl4, OPL4_REG_MISC + voice->number, voice->reg_misc);
 401}
 402
 403static void snd_opl4_update_vibrato_depth(struct snd_opl4 *opl4,
 404                                          struct opl4_voice *voice)
 405{
 406        int depth;
 407
 408        if (voice->chan->drum_channel)
 409                return;
 410        depth = (7 - voice->sound->vibrato)
 411                * (voice->chan->control[MIDI_CTL_VIBRATO_DEPTH] & 0x7f);
 412        depth = (depth >> 7) + voice->sound->vibrato;
 413        voice->reg_lfo_vibrato &= ~OPL4_VIBRATO_DEPTH_MASK;
 414        voice->reg_lfo_vibrato |= depth & OPL4_VIBRATO_DEPTH_MASK;
 415        snd_opl4_write(opl4, OPL4_REG_LFO_VIBRATO + voice->number,
 416                       voice->reg_lfo_vibrato);
 417}
 418
 419static void snd_opl4_update_pitch(struct snd_opl4 *opl4,
 420                                  struct opl4_voice *voice)
 421{
 422        struct snd_midi_channel *chan = voice->chan;
 423        int note, pitch, octave;
 424
 425        note = chan->drum_channel ? 60 : voice->note;
 426        /*
 427         * pitch is in 100/128 cents, so 0x80 is one semitone and
 428         * 0x600 is one octave.
 429         */
 430        pitch = ((note - 60) << 7) * voice->sound->key_scaling / 100 + (60 << 7);
 431        pitch += voice->sound->pitch_offset;
 432        if (!chan->drum_channel)
 433                pitch += chan->gm_rpn_coarse_tuning;
 434        pitch += chan->gm_rpn_fine_tuning >> 7;
 435        pitch += chan->midi_pitchbend * chan->gm_rpn_pitch_bend_range / 0x2000;
 436        if (pitch < 0)
 437                pitch = 0;
 438        else if (pitch >= 0x6000)
 439                pitch = 0x5fff;
 440        octave = pitch / 0x600 - 8;
 441        pitch = snd_opl4_pitch_map[pitch % 0x600];
 442
 443        snd_opl4_write(opl4, OPL4_REG_OCTAVE + voice->number,
 444                       (octave << 4) | ((pitch >> 7) & OPL4_F_NUMBER_HIGH_MASK));
 445        voice->reg_f_number = (voice->reg_f_number & OPL4_TONE_NUMBER_BIT8)
 446                | ((pitch << 1) & OPL4_F_NUMBER_LOW_MASK);
 447        snd_opl4_write(opl4, OPL4_REG_F_NUMBER + voice->number, voice->reg_f_number);
 448}
 449
 450static void snd_opl4_update_tone_parameters(struct snd_opl4 *opl4,
 451                                            struct opl4_voice *voice)
 452{
 453        snd_opl4_write(opl4, OPL4_REG_ATTACK_DECAY1 + voice->number,
 454                       voice->sound->reg_attack_decay1);
 455        snd_opl4_write(opl4, OPL4_REG_LEVEL_DECAY2 + voice->number,
 456                       voice->sound->reg_level_decay2);
 457        snd_opl4_write(opl4, OPL4_REG_RELEASE_CORRECTION + voice->number,
 458                       voice->sound->reg_release_correction);
 459        snd_opl4_write(opl4, OPL4_REG_TREMOLO + voice->number,
 460                       voice->sound->reg_tremolo);
 461}
 462
 463/* allocate one voice */
 464static struct opl4_voice *snd_opl4_get_voice(struct snd_opl4 *opl4)
 465{
 466        /* first, try to get the oldest key-off voice */
 467        if (!list_empty(&opl4->off_voices))
 468                return list_entry(opl4->off_voices.next, struct opl4_voice, list);
 469        /* then get the oldest key-on voice */
 470        snd_BUG_ON(list_empty(&opl4->on_voices));
 471        return list_entry(opl4->on_voices.next, struct opl4_voice, list);
 472}
 473
 474static void snd_opl4_wait_for_wave_headers(struct snd_opl4 *opl4)
 475{
 476        int timeout = 200;
 477
 478        while ((inb(opl4->fm_port) & OPL4_STATUS_LOAD) && --timeout > 0)
 479                udelay(10);
 480}
 481
 482void snd_opl4_note_on(void *private_data, int note, int vel, struct snd_midi_channel *chan)
 483{
 484        struct snd_opl4 *opl4 = private_data;
 485        const struct opl4_region_ptr *regions;
 486        struct opl4_voice *voice[2];
 487        const struct opl4_sound *sound[2];
 488        int voices = 0, i;
 489        unsigned long flags;
 490
 491        /* determine the number of voices and voice parameters */
 492        i = chan->drum_channel ? 0x80 : (chan->midi_program & 0x7f);
 493        regions = &snd_yrw801_regions[i];
 494        for (i = 0; i < regions->count; i++) {
 495                if (note >= regions->regions[i].key_min &&
 496                    note <= regions->regions[i].key_max) {
 497                        sound[voices] = &regions->regions[i].sound;
 498                        if (++voices >= 2)
 499                                break;
 500                }
 501        }
 502
 503        /* allocate and initialize the needed voices */
 504        spin_lock_irqsave(&opl4->reg_lock, flags);
 505        for (i = 0; i < voices; i++) {
 506                voice[i] = snd_opl4_get_voice(opl4);
 507                list_del(&voice[i]->list);
 508                list_add_tail(&voice[i]->list, &opl4->on_voices);
 509                voice[i]->chan = chan;
 510                voice[i]->note = note;
 511                voice[i]->velocity = vel & 0x7f;
 512                voice[i]->sound = sound[i];
 513        }
 514
 515        /* set tone number (triggers header loading) */
 516        for (i = 0; i < voices; i++) {
 517                voice[i]->reg_f_number =
 518                        (sound[i]->tone >> 8) & OPL4_TONE_NUMBER_BIT8;
 519                snd_opl4_write(opl4, OPL4_REG_F_NUMBER + voice[i]->number,
 520                               voice[i]->reg_f_number);
 521                snd_opl4_write(opl4, OPL4_REG_TONE_NUMBER + voice[i]->number,
 522                               sound[i]->tone & 0xff);
 523        }
 524
 525        /* set parameters which can be set while loading */
 526        for (i = 0; i < voices; i++) {
 527                voice[i]->reg_misc = OPL4_LFO_RESET_BIT;
 528                snd_opl4_update_pan(opl4, voice[i]);
 529                snd_opl4_update_pitch(opl4, voice[i]);
 530                voice[i]->level_direct = OPL4_LEVEL_DIRECT_BIT;
 531                snd_opl4_update_volume(opl4, voice[i]);
 532        }
 533        spin_unlock_irqrestore(&opl4->reg_lock, flags);
 534
 535        /* wait for completion of loading */
 536        snd_opl4_wait_for_wave_headers(opl4);
 537
 538        /* set remaining parameters */
 539        spin_lock_irqsave(&opl4->reg_lock, flags);
 540        for (i = 0; i < voices; i++) {
 541                snd_opl4_update_tone_parameters(opl4, voice[i]);
 542                voice[i]->reg_lfo_vibrato = voice[i]->sound->reg_lfo_vibrato;
 543                snd_opl4_update_vibrato_depth(opl4, voice[i]);
 544        }
 545
 546        /* finally, switch on all voices */
 547        for (i = 0; i < voices; i++) {
 548                voice[i]->reg_misc =
 549                        (voice[i]->reg_misc & 0x1f) | OPL4_KEY_ON_BIT;
 550                snd_opl4_write(opl4, OPL4_REG_MISC + voice[i]->number,
 551                               voice[i]->reg_misc);
 552        }
 553        spin_unlock_irqrestore(&opl4->reg_lock, flags);
 554}
 555
 556static void snd_opl4_voice_off(struct snd_opl4 *opl4, struct opl4_voice *voice)
 557{
 558        list_del(&voice->list);
 559        list_add_tail(&voice->list, &opl4->off_voices);
 560
 561        voice->reg_misc &= ~OPL4_KEY_ON_BIT;
 562        snd_opl4_write(opl4, OPL4_REG_MISC + voice->number, voice->reg_misc);
 563}
 564
 565void snd_opl4_note_off(void *private_data, int note, int vel, struct snd_midi_channel *chan)
 566{
 567        struct snd_opl4 *opl4 = private_data;
 568
 569        snd_opl4_do_for_note(opl4, note, chan, snd_opl4_voice_off);
 570}
 571
 572static void snd_opl4_terminate_voice(struct snd_opl4 *opl4, struct opl4_voice *voice)
 573{
 574        list_del(&voice->list);
 575        list_add_tail(&voice->list, &opl4->off_voices);
 576
 577        voice->reg_misc = (voice->reg_misc & ~OPL4_KEY_ON_BIT) | OPL4_DAMP_BIT;
 578        snd_opl4_write(opl4, OPL4_REG_MISC + voice->number, voice->reg_misc);
 579}
 580
 581void snd_opl4_terminate_note(void *private_data, int note, struct snd_midi_channel *chan)
 582{
 583        struct snd_opl4 *opl4 = private_data;
 584
 585        snd_opl4_do_for_note(opl4, note, chan, snd_opl4_terminate_voice);
 586}
 587
 588void snd_opl4_control(void *private_data, int type, struct snd_midi_channel *chan)
 589{
 590        struct snd_opl4 *opl4 = private_data;
 591
 592        switch (type) {
 593        case MIDI_CTL_MSB_MODWHEEL:
 594                chan->control[MIDI_CTL_VIBRATO_DEPTH] = chan->control[MIDI_CTL_MSB_MODWHEEL];
 595                snd_opl4_do_for_channel(opl4, chan, snd_opl4_update_vibrato_depth);
 596                break;
 597        case MIDI_CTL_MSB_MAIN_VOLUME:
 598                snd_opl4_do_for_channel(opl4, chan, snd_opl4_update_volume);
 599                break;
 600        case MIDI_CTL_MSB_PAN:
 601                snd_opl4_do_for_channel(opl4, chan, snd_opl4_update_pan);
 602                break;
 603        case MIDI_CTL_MSB_EXPRESSION:
 604                snd_opl4_do_for_channel(opl4, chan, snd_opl4_update_volume);
 605                break;
 606        case MIDI_CTL_VIBRATO_RATE:
 607                /* not yet supported */
 608                break;
 609        case MIDI_CTL_VIBRATO_DEPTH:
 610                snd_opl4_do_for_channel(opl4, chan, snd_opl4_update_vibrato_depth);
 611                break;
 612        case MIDI_CTL_VIBRATO_DELAY:
 613                /* not yet supported */
 614                break;
 615        case MIDI_CTL_E1_REVERB_DEPTH:
 616                /*
 617                 * Each OPL4 voice has a bit called "Pseudo-Reverb", but
 618                 * IMHO _not_ using it enhances the listening experience.
 619                 */
 620                break;
 621        case MIDI_CTL_PITCHBEND:
 622                snd_opl4_do_for_channel(opl4, chan, snd_opl4_update_pitch);
 623                break;
 624        }
 625}
 626
 627void snd_opl4_sysex(void *private_data, unsigned char *buf, int len,
 628                    int parsed, struct snd_midi_channel_set *chset)
 629{
 630        struct snd_opl4 *opl4 = private_data;
 631
 632        if (parsed == SNDRV_MIDI_SYSEX_GS_MASTER_VOLUME)
 633                snd_opl4_do_for_all(opl4, snd_opl4_update_volume);
 634}
 635
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.