cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

opl4_synth.c (23330B)


      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 <linux/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 const 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_move_tail(&voice[i]->list, &opl4->on_voices);
    508		voice[i]->chan = chan;
    509		voice[i]->note = note;
    510		voice[i]->velocity = vel & 0x7f;
    511		voice[i]->sound = sound[i];
    512	}
    513
    514	/* set tone number (triggers header loading) */
    515	for (i = 0; i < voices; i++) {
    516		voice[i]->reg_f_number =
    517			(sound[i]->tone >> 8) & OPL4_TONE_NUMBER_BIT8;
    518		snd_opl4_write(opl4, OPL4_REG_F_NUMBER + voice[i]->number,
    519			       voice[i]->reg_f_number);
    520		snd_opl4_write(opl4, OPL4_REG_TONE_NUMBER + voice[i]->number,
    521			       sound[i]->tone & 0xff);
    522	}
    523
    524	/* set parameters which can be set while loading */
    525	for (i = 0; i < voices; i++) {
    526		voice[i]->reg_misc = OPL4_LFO_RESET_BIT;
    527		snd_opl4_update_pan(opl4, voice[i]);
    528		snd_opl4_update_pitch(opl4, voice[i]);
    529		voice[i]->level_direct = OPL4_LEVEL_DIRECT_BIT;
    530		snd_opl4_update_volume(opl4, voice[i]);
    531	}
    532	spin_unlock_irqrestore(&opl4->reg_lock, flags);
    533
    534	/* wait for completion of loading */
    535	snd_opl4_wait_for_wave_headers(opl4);
    536
    537	/* set remaining parameters */
    538	spin_lock_irqsave(&opl4->reg_lock, flags);
    539	for (i = 0; i < voices; i++) {
    540		snd_opl4_update_tone_parameters(opl4, voice[i]);
    541		voice[i]->reg_lfo_vibrato = voice[i]->sound->reg_lfo_vibrato;
    542		snd_opl4_update_vibrato_depth(opl4, voice[i]);
    543	}
    544
    545	/* finally, switch on all voices */
    546	for (i = 0; i < voices; i++) {
    547		voice[i]->reg_misc =
    548			(voice[i]->reg_misc & 0x1f) | OPL4_KEY_ON_BIT;
    549		snd_opl4_write(opl4, OPL4_REG_MISC + voice[i]->number,
    550			       voice[i]->reg_misc);
    551	}
    552	spin_unlock_irqrestore(&opl4->reg_lock, flags);
    553}
    554
    555static void snd_opl4_voice_off(struct snd_opl4 *opl4, struct opl4_voice *voice)
    556{
    557	list_move_tail(&voice->list, &opl4->off_voices);
    558
    559	voice->reg_misc &= ~OPL4_KEY_ON_BIT;
    560	snd_opl4_write(opl4, OPL4_REG_MISC + voice->number, voice->reg_misc);
    561}
    562
    563void snd_opl4_note_off(void *private_data, int note, int vel, struct snd_midi_channel *chan)
    564{
    565	struct snd_opl4 *opl4 = private_data;
    566
    567	snd_opl4_do_for_note(opl4, note, chan, snd_opl4_voice_off);
    568}
    569
    570static void snd_opl4_terminate_voice(struct snd_opl4 *opl4, struct opl4_voice *voice)
    571{
    572	list_move_tail(&voice->list, &opl4->off_voices);
    573
    574	voice->reg_misc = (voice->reg_misc & ~OPL4_KEY_ON_BIT) | OPL4_DAMP_BIT;
    575	snd_opl4_write(opl4, OPL4_REG_MISC + voice->number, voice->reg_misc);
    576}
    577
    578void snd_opl4_terminate_note(void *private_data, int note, struct snd_midi_channel *chan)
    579{
    580	struct snd_opl4 *opl4 = private_data;
    581
    582	snd_opl4_do_for_note(opl4, note, chan, snd_opl4_terminate_voice);
    583}
    584
    585void snd_opl4_control(void *private_data, int type, struct snd_midi_channel *chan)
    586{
    587	struct snd_opl4 *opl4 = private_data;
    588
    589	switch (type) {
    590	case MIDI_CTL_MSB_MODWHEEL:
    591		chan->control[MIDI_CTL_VIBRATO_DEPTH] = chan->control[MIDI_CTL_MSB_MODWHEEL];
    592		snd_opl4_do_for_channel(opl4, chan, snd_opl4_update_vibrato_depth);
    593		break;
    594	case MIDI_CTL_MSB_MAIN_VOLUME:
    595		snd_opl4_do_for_channel(opl4, chan, snd_opl4_update_volume);
    596		break;
    597	case MIDI_CTL_MSB_PAN:
    598		snd_opl4_do_for_channel(opl4, chan, snd_opl4_update_pan);
    599		break;
    600	case MIDI_CTL_MSB_EXPRESSION:
    601		snd_opl4_do_for_channel(opl4, chan, snd_opl4_update_volume);
    602		break;
    603	case MIDI_CTL_VIBRATO_RATE:
    604		/* not yet supported */
    605		break;
    606	case MIDI_CTL_VIBRATO_DEPTH:
    607		snd_opl4_do_for_channel(opl4, chan, snd_opl4_update_vibrato_depth);
    608		break;
    609	case MIDI_CTL_VIBRATO_DELAY:
    610		/* not yet supported */
    611		break;
    612	case MIDI_CTL_E1_REVERB_DEPTH:
    613		/*
    614		 * Each OPL4 voice has a bit called "Pseudo-Reverb", but
    615		 * IMHO _not_ using it enhances the listening experience.
    616		 */
    617		break;
    618	case MIDI_CTL_PITCHBEND:
    619		snd_opl4_do_for_channel(opl4, chan, snd_opl4_update_pitch);
    620		break;
    621	}
    622}
    623
    624void snd_opl4_sysex(void *private_data, unsigned char *buf, int len,
    625		    int parsed, struct snd_midi_channel_set *chset)
    626{
    627	struct snd_opl4 *opl4 = private_data;
    628
    629	if (parsed == SNDRV_MIDI_SYSEX_GS_MASTER_VOLUME)
    630		snd_opl4_do_for_all(opl4, snd_opl4_update_volume);
    631}