Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * OPL4 MIDI synthesizer functions
0003  *
0004  * Copyright (c) 2003 by Clemens Ladisch <clemens@ladisch.de>
0005  * All rights reserved.
0006  *
0007  * Redistribution and use in source and binary forms, with or without
0008  * modification, are permitted provided that the following conditions
0009  * are met:
0010  * 1. Redistributions of source code must retain the above copyright
0011  *    notice, this list of conditions, and the following disclaimer,
0012  *    without modification.
0013  * 2. The name of the author may not be used to endorse or promote products
0014  *    derived from this software without specific prior written permission.
0015  *
0016  * Alternatively, this software may be distributed and/or modified under the
0017  * terms of the GNU General Public License as published by the Free Software
0018  * Foundation; either version 2 of the License, or (at your option) any later
0019  * version.
0020  *
0021  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
0022  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0023  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0024  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
0025  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
0026  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
0027  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
0028  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
0029  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
0030  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
0031  * SUCH DAMAGE.
0032  */
0033 
0034 #include "opl4_local.h"
0035 #include <linux/delay.h>
0036 #include <linux/io.h>
0037 #include <sound/asoundef.h>
0038 
0039 /* GM2 controllers */
0040 #ifndef MIDI_CTL_RELEASE_TIME
0041 #define MIDI_CTL_RELEASE_TIME   0x48
0042 #define MIDI_CTL_ATTACK_TIME    0x49
0043 #define MIDI_CTL_DECAY_TIME 0x4b
0044 #define MIDI_CTL_VIBRATO_RATE   0x4c
0045 #define MIDI_CTL_VIBRATO_DEPTH  0x4d
0046 #define MIDI_CTL_VIBRATO_DELAY  0x4e
0047 #endif
0048 
0049 /*
0050  * This table maps 100/128 cents to F_NUMBER.
0051  */
0052 static const s16 snd_opl4_pitch_map[0x600] = {
0053     0x000,0x000,0x001,0x001,0x002,0x002,0x003,0x003,
0054     0x004,0x004,0x005,0x005,0x006,0x006,0x006,0x007,
0055     0x007,0x008,0x008,0x009,0x009,0x00a,0x00a,0x00b,
0056     0x00b,0x00c,0x00c,0x00d,0x00d,0x00d,0x00e,0x00e,
0057     0x00f,0x00f,0x010,0x010,0x011,0x011,0x012,0x012,
0058     0x013,0x013,0x014,0x014,0x015,0x015,0x015,0x016,
0059     0x016,0x017,0x017,0x018,0x018,0x019,0x019,0x01a,
0060     0x01a,0x01b,0x01b,0x01c,0x01c,0x01d,0x01d,0x01e,
0061     0x01e,0x01e,0x01f,0x01f,0x020,0x020,0x021,0x021,
0062     0x022,0x022,0x023,0x023,0x024,0x024,0x025,0x025,
0063     0x026,0x026,0x027,0x027,0x028,0x028,0x029,0x029,
0064     0x029,0x02a,0x02a,0x02b,0x02b,0x02c,0x02c,0x02d,
0065     0x02d,0x02e,0x02e,0x02f,0x02f,0x030,0x030,0x031,
0066     0x031,0x032,0x032,0x033,0x033,0x034,0x034,0x035,
0067     0x035,0x036,0x036,0x037,0x037,0x038,0x038,0x038,
0068     0x039,0x039,0x03a,0x03a,0x03b,0x03b,0x03c,0x03c,
0069     0x03d,0x03d,0x03e,0x03e,0x03f,0x03f,0x040,0x040,
0070     0x041,0x041,0x042,0x042,0x043,0x043,0x044,0x044,
0071     0x045,0x045,0x046,0x046,0x047,0x047,0x048,0x048,
0072     0x049,0x049,0x04a,0x04a,0x04b,0x04b,0x04c,0x04c,
0073     0x04d,0x04d,0x04e,0x04e,0x04f,0x04f,0x050,0x050,
0074     0x051,0x051,0x052,0x052,0x053,0x053,0x054,0x054,
0075     0x055,0x055,0x056,0x056,0x057,0x057,0x058,0x058,
0076     0x059,0x059,0x05a,0x05a,0x05b,0x05b,0x05c,0x05c,
0077     0x05d,0x05d,0x05e,0x05e,0x05f,0x05f,0x060,0x060,
0078     0x061,0x061,0x062,0x062,0x063,0x063,0x064,0x064,
0079     0x065,0x065,0x066,0x066,0x067,0x067,0x068,0x068,
0080     0x069,0x069,0x06a,0x06a,0x06b,0x06b,0x06c,0x06c,
0081     0x06d,0x06d,0x06e,0x06e,0x06f,0x06f,0x070,0x071,
0082     0x071,0x072,0x072,0x073,0x073,0x074,0x074,0x075,
0083     0x075,0x076,0x076,0x077,0x077,0x078,0x078,0x079,
0084     0x079,0x07a,0x07a,0x07b,0x07b,0x07c,0x07c,0x07d,
0085     0x07d,0x07e,0x07e,0x07f,0x07f,0x080,0x081,0x081,
0086     0x082,0x082,0x083,0x083,0x084,0x084,0x085,0x085,
0087     0x086,0x086,0x087,0x087,0x088,0x088,0x089,0x089,
0088     0x08a,0x08a,0x08b,0x08b,0x08c,0x08d,0x08d,0x08e,
0089     0x08e,0x08f,0x08f,0x090,0x090,0x091,0x091,0x092,
0090     0x092,0x093,0x093,0x094,0x094,0x095,0x096,0x096,
0091     0x097,0x097,0x098,0x098,0x099,0x099,0x09a,0x09a,
0092     0x09b,0x09b,0x09c,0x09c,0x09d,0x09d,0x09e,0x09f,
0093     0x09f,0x0a0,0x0a0,0x0a1,0x0a1,0x0a2,0x0a2,0x0a3,
0094     0x0a3,0x0a4,0x0a4,0x0a5,0x0a6,0x0a6,0x0a7,0x0a7,
0095     0x0a8,0x0a8,0x0a9,0x0a9,0x0aa,0x0aa,0x0ab,0x0ab,
0096     0x0ac,0x0ad,0x0ad,0x0ae,0x0ae,0x0af,0x0af,0x0b0,
0097     0x0b0,0x0b1,0x0b1,0x0b2,0x0b2,0x0b3,0x0b4,0x0b4,
0098     0x0b5,0x0b5,0x0b6,0x0b6,0x0b7,0x0b7,0x0b8,0x0b8,
0099     0x0b9,0x0ba,0x0ba,0x0bb,0x0bb,0x0bc,0x0bc,0x0bd,
0100     0x0bd,0x0be,0x0be,0x0bf,0x0c0,0x0c0,0x0c1,0x0c1,
0101     0x0c2,0x0c2,0x0c3,0x0c3,0x0c4,0x0c4,0x0c5,0x0c6,
0102     0x0c6,0x0c7,0x0c7,0x0c8,0x0c8,0x0c9,0x0c9,0x0ca,
0103     0x0cb,0x0cb,0x0cc,0x0cc,0x0cd,0x0cd,0x0ce,0x0ce,
0104     0x0cf,0x0d0,0x0d0,0x0d1,0x0d1,0x0d2,0x0d2,0x0d3,
0105     0x0d3,0x0d4,0x0d5,0x0d5,0x0d6,0x0d6,0x0d7,0x0d7,
0106     0x0d8,0x0d8,0x0d9,0x0da,0x0da,0x0db,0x0db,0x0dc,
0107     0x0dc,0x0dd,0x0de,0x0de,0x0df,0x0df,0x0e0,0x0e0,
0108     0x0e1,0x0e1,0x0e2,0x0e3,0x0e3,0x0e4,0x0e4,0x0e5,
0109     0x0e5,0x0e6,0x0e7,0x0e7,0x0e8,0x0e8,0x0e9,0x0e9,
0110     0x0ea,0x0eb,0x0eb,0x0ec,0x0ec,0x0ed,0x0ed,0x0ee,
0111     0x0ef,0x0ef,0x0f0,0x0f0,0x0f1,0x0f1,0x0f2,0x0f3,
0112     0x0f3,0x0f4,0x0f4,0x0f5,0x0f5,0x0f6,0x0f7,0x0f7,
0113     0x0f8,0x0f8,0x0f9,0x0f9,0x0fa,0x0fb,0x0fb,0x0fc,
0114     0x0fc,0x0fd,0x0fd,0x0fe,0x0ff,0x0ff,0x100,0x100,
0115     0x101,0x101,0x102,0x103,0x103,0x104,0x104,0x105,
0116     0x106,0x106,0x107,0x107,0x108,0x108,0x109,0x10a,
0117     0x10a,0x10b,0x10b,0x10c,0x10c,0x10d,0x10e,0x10e,
0118     0x10f,0x10f,0x110,0x111,0x111,0x112,0x112,0x113,
0119     0x114,0x114,0x115,0x115,0x116,0x116,0x117,0x118,
0120     0x118,0x119,0x119,0x11a,0x11b,0x11b,0x11c,0x11c,
0121     0x11d,0x11e,0x11e,0x11f,0x11f,0x120,0x120,0x121,
0122     0x122,0x122,0x123,0x123,0x124,0x125,0x125,0x126,
0123     0x126,0x127,0x128,0x128,0x129,0x129,0x12a,0x12b,
0124     0x12b,0x12c,0x12c,0x12d,0x12e,0x12e,0x12f,0x12f,
0125     0x130,0x131,0x131,0x132,0x132,0x133,0x134,0x134,
0126     0x135,0x135,0x136,0x137,0x137,0x138,0x138,0x139,
0127     0x13a,0x13a,0x13b,0x13b,0x13c,0x13d,0x13d,0x13e,
0128     0x13e,0x13f,0x140,0x140,0x141,0x141,0x142,0x143,
0129     0x143,0x144,0x144,0x145,0x146,0x146,0x147,0x148,
0130     0x148,0x149,0x149,0x14a,0x14b,0x14b,0x14c,0x14c,
0131     0x14d,0x14e,0x14e,0x14f,0x14f,0x150,0x151,0x151,
0132     0x152,0x153,0x153,0x154,0x154,0x155,0x156,0x156,
0133     0x157,0x157,0x158,0x159,0x159,0x15a,0x15b,0x15b,
0134     0x15c,0x15c,0x15d,0x15e,0x15e,0x15f,0x160,0x160,
0135     0x161,0x161,0x162,0x163,0x163,0x164,0x165,0x165,
0136     0x166,0x166,0x167,0x168,0x168,0x169,0x16a,0x16a,
0137     0x16b,0x16b,0x16c,0x16d,0x16d,0x16e,0x16f,0x16f,
0138     0x170,0x170,0x171,0x172,0x172,0x173,0x174,0x174,
0139     0x175,0x175,0x176,0x177,0x177,0x178,0x179,0x179,
0140     0x17a,0x17a,0x17b,0x17c,0x17c,0x17d,0x17e,0x17e,
0141     0x17f,0x180,0x180,0x181,0x181,0x182,0x183,0x183,
0142     0x184,0x185,0x185,0x186,0x187,0x187,0x188,0x188,
0143     0x189,0x18a,0x18a,0x18b,0x18c,0x18c,0x18d,0x18e,
0144     0x18e,0x18f,0x190,0x190,0x191,0x191,0x192,0x193,
0145     0x193,0x194,0x195,0x195,0x196,0x197,0x197,0x198,
0146     0x199,0x199,0x19a,0x19a,0x19b,0x19c,0x19c,0x19d,
0147     0x19e,0x19e,0x19f,0x1a0,0x1a0,0x1a1,0x1a2,0x1a2,
0148     0x1a3,0x1a4,0x1a4,0x1a5,0x1a6,0x1a6,0x1a7,0x1a8,
0149     0x1a8,0x1a9,0x1a9,0x1aa,0x1ab,0x1ab,0x1ac,0x1ad,
0150     0x1ad,0x1ae,0x1af,0x1af,0x1b0,0x1b1,0x1b1,0x1b2,
0151     0x1b3,0x1b3,0x1b4,0x1b5,0x1b5,0x1b6,0x1b7,0x1b7,
0152     0x1b8,0x1b9,0x1b9,0x1ba,0x1bb,0x1bb,0x1bc,0x1bd,
0153     0x1bd,0x1be,0x1bf,0x1bf,0x1c0,0x1c1,0x1c1,0x1c2,
0154     0x1c3,0x1c3,0x1c4,0x1c5,0x1c5,0x1c6,0x1c7,0x1c7,
0155     0x1c8,0x1c9,0x1c9,0x1ca,0x1cb,0x1cb,0x1cc,0x1cd,
0156     0x1cd,0x1ce,0x1cf,0x1cf,0x1d0,0x1d1,0x1d1,0x1d2,
0157     0x1d3,0x1d3,0x1d4,0x1d5,0x1d5,0x1d6,0x1d7,0x1d7,
0158     0x1d8,0x1d9,0x1d9,0x1da,0x1db,0x1db,0x1dc,0x1dd,
0159     0x1dd,0x1de,0x1df,0x1df,0x1e0,0x1e1,0x1e1,0x1e2,
0160     0x1e3,0x1e4,0x1e4,0x1e5,0x1e6,0x1e6,0x1e7,0x1e8,
0161     0x1e8,0x1e9,0x1ea,0x1ea,0x1eb,0x1ec,0x1ec,0x1ed,
0162     0x1ee,0x1ee,0x1ef,0x1f0,0x1f0,0x1f1,0x1f2,0x1f3,
0163     0x1f3,0x1f4,0x1f5,0x1f5,0x1f6,0x1f7,0x1f7,0x1f8,
0164     0x1f9,0x1f9,0x1fa,0x1fb,0x1fb,0x1fc,0x1fd,0x1fe,
0165     0x1fe,0x1ff,0x200,0x200,0x201,0x202,0x202,0x203,
0166     0x204,0x205,0x205,0x206,0x207,0x207,0x208,0x209,
0167     0x209,0x20a,0x20b,0x20b,0x20c,0x20d,0x20e,0x20e,
0168     0x20f,0x210,0x210,0x211,0x212,0x212,0x213,0x214,
0169     0x215,0x215,0x216,0x217,0x217,0x218,0x219,0x21a,
0170     0x21a,0x21b,0x21c,0x21c,0x21d,0x21e,0x21e,0x21f,
0171     0x220,0x221,0x221,0x222,0x223,0x223,0x224,0x225,
0172     0x226,0x226,0x227,0x228,0x228,0x229,0x22a,0x22b,
0173     0x22b,0x22c,0x22d,0x22d,0x22e,0x22f,0x230,0x230,
0174     0x231,0x232,0x232,0x233,0x234,0x235,0x235,0x236,
0175     0x237,0x237,0x238,0x239,0x23a,0x23a,0x23b,0x23c,
0176     0x23c,0x23d,0x23e,0x23f,0x23f,0x240,0x241,0x241,
0177     0x242,0x243,0x244,0x244,0x245,0x246,0x247,0x247,
0178     0x248,0x249,0x249,0x24a,0x24b,0x24c,0x24c,0x24d,
0179     0x24e,0x24f,0x24f,0x250,0x251,0x251,0x252,0x253,
0180     0x254,0x254,0x255,0x256,0x257,0x257,0x258,0x259,
0181     0x259,0x25a,0x25b,0x25c,0x25c,0x25d,0x25e,0x25f,
0182     0x25f,0x260,0x261,0x262,0x262,0x263,0x264,0x265,
0183     0x265,0x266,0x267,0x267,0x268,0x269,0x26a,0x26a,
0184     0x26b,0x26c,0x26d,0x26d,0x26e,0x26f,0x270,0x270,
0185     0x271,0x272,0x273,0x273,0x274,0x275,0x276,0x276,
0186     0x277,0x278,0x279,0x279,0x27a,0x27b,0x27c,0x27c,
0187     0x27d,0x27e,0x27f,0x27f,0x280,0x281,0x282,0x282,
0188     0x283,0x284,0x285,0x285,0x286,0x287,0x288,0x288,
0189     0x289,0x28a,0x28b,0x28b,0x28c,0x28d,0x28e,0x28e,
0190     0x28f,0x290,0x291,0x291,0x292,0x293,0x294,0x294,
0191     0x295,0x296,0x297,0x298,0x298,0x299,0x29a,0x29b,
0192     0x29b,0x29c,0x29d,0x29e,0x29e,0x29f,0x2a0,0x2a1,
0193     0x2a1,0x2a2,0x2a3,0x2a4,0x2a5,0x2a5,0x2a6,0x2a7,
0194     0x2a8,0x2a8,0x2a9,0x2aa,0x2ab,0x2ab,0x2ac,0x2ad,
0195     0x2ae,0x2af,0x2af,0x2b0,0x2b1,0x2b2,0x2b2,0x2b3,
0196     0x2b4,0x2b5,0x2b5,0x2b6,0x2b7,0x2b8,0x2b9,0x2b9,
0197     0x2ba,0x2bb,0x2bc,0x2bc,0x2bd,0x2be,0x2bf,0x2c0,
0198     0x2c0,0x2c1,0x2c2,0x2c3,0x2c4,0x2c4,0x2c5,0x2c6,
0199     0x2c7,0x2c7,0x2c8,0x2c9,0x2ca,0x2cb,0x2cb,0x2cc,
0200     0x2cd,0x2ce,0x2ce,0x2cf,0x2d0,0x2d1,0x2d2,0x2d2,
0201     0x2d3,0x2d4,0x2d5,0x2d6,0x2d6,0x2d7,0x2d8,0x2d9,
0202     0x2da,0x2da,0x2db,0x2dc,0x2dd,0x2dd,0x2de,0x2df,
0203     0x2e0,0x2e1,0x2e1,0x2e2,0x2e3,0x2e4,0x2e5,0x2e5,
0204     0x2e6,0x2e7,0x2e8,0x2e9,0x2e9,0x2ea,0x2eb,0x2ec,
0205     0x2ed,0x2ed,0x2ee,0x2ef,0x2f0,0x2f1,0x2f1,0x2f2,
0206     0x2f3,0x2f4,0x2f5,0x2f5,0x2f6,0x2f7,0x2f8,0x2f9,
0207     0x2f9,0x2fa,0x2fb,0x2fc,0x2fd,0x2fd,0x2fe,0x2ff,
0208     0x300,0x301,0x302,0x302,0x303,0x304,0x305,0x306,
0209     0x306,0x307,0x308,0x309,0x30a,0x30a,0x30b,0x30c,
0210     0x30d,0x30e,0x30f,0x30f,0x310,0x311,0x312,0x313,
0211     0x313,0x314,0x315,0x316,0x317,0x318,0x318,0x319,
0212     0x31a,0x31b,0x31c,0x31c,0x31d,0x31e,0x31f,0x320,
0213     0x321,0x321,0x322,0x323,0x324,0x325,0x326,0x326,
0214     0x327,0x328,0x329,0x32a,0x32a,0x32b,0x32c,0x32d,
0215     0x32e,0x32f,0x32f,0x330,0x331,0x332,0x333,0x334,
0216     0x334,0x335,0x336,0x337,0x338,0x339,0x339,0x33a,
0217     0x33b,0x33c,0x33d,0x33e,0x33e,0x33f,0x340,0x341,
0218     0x342,0x343,0x343,0x344,0x345,0x346,0x347,0x348,
0219     0x349,0x349,0x34a,0x34b,0x34c,0x34d,0x34e,0x34e,
0220     0x34f,0x350,0x351,0x352,0x353,0x353,0x354,0x355,
0221     0x356,0x357,0x358,0x359,0x359,0x35a,0x35b,0x35c,
0222     0x35d,0x35e,0x35f,0x35f,0x360,0x361,0x362,0x363,
0223     0x364,0x364,0x365,0x366,0x367,0x368,0x369,0x36a,
0224     0x36a,0x36b,0x36c,0x36d,0x36e,0x36f,0x370,0x370,
0225     0x371,0x372,0x373,0x374,0x375,0x376,0x377,0x377,
0226     0x378,0x379,0x37a,0x37b,0x37c,0x37d,0x37d,0x37e,
0227     0x37f,0x380,0x381,0x382,0x383,0x383,0x384,0x385,
0228     0x386,0x387,0x388,0x389,0x38a,0x38a,0x38b,0x38c,
0229     0x38d,0x38e,0x38f,0x390,0x391,0x391,0x392,0x393,
0230     0x394,0x395,0x396,0x397,0x398,0x398,0x399,0x39a,
0231     0x39b,0x39c,0x39d,0x39e,0x39f,0x39f,0x3a0,0x3a1,
0232     0x3a2,0x3a3,0x3a4,0x3a5,0x3a6,0x3a7,0x3a7,0x3a8,
0233     0x3a9,0x3aa,0x3ab,0x3ac,0x3ad,0x3ae,0x3ae,0x3af,
0234     0x3b0,0x3b1,0x3b2,0x3b3,0x3b4,0x3b5,0x3b6,0x3b6,
0235     0x3b7,0x3b8,0x3b9,0x3ba,0x3bb,0x3bc,0x3bd,0x3be,
0236     0x3bf,0x3bf,0x3c0,0x3c1,0x3c2,0x3c3,0x3c4,0x3c5,
0237     0x3c6,0x3c7,0x3c7,0x3c8,0x3c9,0x3ca,0x3cb,0x3cc,
0238     0x3cd,0x3ce,0x3cf,0x3d0,0x3d1,0x3d1,0x3d2,0x3d3,
0239     0x3d4,0x3d5,0x3d6,0x3d7,0x3d8,0x3d9,0x3da,0x3da,
0240     0x3db,0x3dc,0x3dd,0x3de,0x3df,0x3e0,0x3e1,0x3e2,
0241     0x3e3,0x3e4,0x3e4,0x3e5,0x3e6,0x3e7,0x3e8,0x3e9,
0242     0x3ea,0x3eb,0x3ec,0x3ed,0x3ee,0x3ef,0x3ef,0x3f0,
0243     0x3f1,0x3f2,0x3f3,0x3f4,0x3f5,0x3f6,0x3f7,0x3f8,
0244     0x3f9,0x3fa,0x3fa,0x3fb,0x3fc,0x3fd,0x3fe,0x3ff
0245 };
0246 
0247 /*
0248  * Attenuation according to GM recommendations, in -0.375 dB units.
0249  * table[v] = 40 * log(v / 127) / -0.375
0250  */
0251 static const unsigned char snd_opl4_volume_table[128] = {
0252     255,224,192,173,160,150,141,134,
0253     128,122,117,113,109,105,102, 99,
0254      96, 93, 90, 88, 85, 83, 81, 79,
0255      77, 75, 73, 71, 70, 68, 67, 65,
0256      64, 62, 61, 59, 58, 57, 56, 54,
0257      53, 52, 51, 50, 49, 48, 47, 46,
0258      45, 44, 43, 42, 41, 40, 39, 39,
0259      38, 37, 36, 35, 34, 34, 33, 32,
0260      31, 31, 30, 29, 29, 28, 27, 27,
0261      26, 25, 25, 24, 24, 23, 22, 22,
0262      21, 21, 20, 19, 19, 18, 18, 17,
0263      17, 16, 16, 15, 15, 14, 14, 13,
0264      13, 12, 12, 11, 11, 10, 10,  9,
0265       9,  9,  8,  8,  7,  7,  6,  6,
0266       6,  5,  5,  4,  4,  4,  3,  3,
0267       2,  2,  2,  1,  1,  0,  0,  0
0268 };
0269 
0270 /*
0271  * Initializes all voices.
0272  */
0273 void snd_opl4_synth_reset(struct snd_opl4 *opl4)
0274 {
0275     unsigned long flags;
0276     int i;
0277 
0278     spin_lock_irqsave(&opl4->reg_lock, flags);
0279     for (i = 0; i < OPL4_MAX_VOICES; i++)
0280         snd_opl4_write(opl4, OPL4_REG_MISC + i, OPL4_DAMP_BIT);
0281     spin_unlock_irqrestore(&opl4->reg_lock, flags);
0282 
0283     INIT_LIST_HEAD(&opl4->off_voices);
0284     INIT_LIST_HEAD(&opl4->on_voices);
0285     memset(opl4->voices, 0, sizeof(opl4->voices));
0286     for (i = 0; i < OPL4_MAX_VOICES; i++) {
0287         opl4->voices[i].number = i;
0288         list_add_tail(&opl4->voices[i].list, &opl4->off_voices);
0289     }
0290 
0291     snd_midi_channel_set_clear(opl4->chset);
0292 }
0293 
0294 /*
0295  * Shuts down all voices.
0296  */
0297 void snd_opl4_synth_shutdown(struct snd_opl4 *opl4)
0298 {
0299     unsigned long flags;
0300     int i;
0301 
0302     spin_lock_irqsave(&opl4->reg_lock, flags);
0303     for (i = 0; i < OPL4_MAX_VOICES; i++)
0304         snd_opl4_write(opl4, OPL4_REG_MISC + i,
0305                    opl4->voices[i].reg_misc & ~OPL4_KEY_ON_BIT);
0306     spin_unlock_irqrestore(&opl4->reg_lock, flags);
0307 }
0308 
0309 /*
0310  * Executes the callback for all voices playing the specified note.
0311  */
0312 static void snd_opl4_do_for_note(struct snd_opl4 *opl4, int note, struct snd_midi_channel *chan,
0313                  void (*func)(struct snd_opl4 *opl4, struct opl4_voice *voice))
0314 {
0315     int i;
0316     unsigned long flags;
0317     struct opl4_voice *voice;
0318 
0319     spin_lock_irqsave(&opl4->reg_lock, flags);
0320     for (i = 0; i < OPL4_MAX_VOICES; i++) {
0321         voice = &opl4->voices[i];
0322         if (voice->chan == chan && voice->note == note) {
0323             func(opl4, voice);
0324         }
0325     }
0326     spin_unlock_irqrestore(&opl4->reg_lock, flags);
0327 }
0328 
0329 /*
0330  * Executes the callback for all voices of to the specified channel.
0331  */
0332 static void snd_opl4_do_for_channel(struct snd_opl4 *opl4,
0333                     struct snd_midi_channel *chan,
0334                     void (*func)(struct snd_opl4 *opl4, struct opl4_voice *voice))
0335 {
0336     int i;
0337     unsigned long flags;
0338     struct opl4_voice *voice;
0339 
0340     spin_lock_irqsave(&opl4->reg_lock, flags);
0341     for (i = 0; i < OPL4_MAX_VOICES; i++) {
0342         voice = &opl4->voices[i];
0343         if (voice->chan == chan) {
0344             func(opl4, voice);
0345         }
0346     }
0347     spin_unlock_irqrestore(&opl4->reg_lock, flags);
0348 }
0349 
0350 /*
0351  * Executes the callback for all active voices.
0352  */
0353 static void snd_opl4_do_for_all(struct snd_opl4 *opl4,
0354                 void (*func)(struct snd_opl4 *opl4, struct opl4_voice *voice))
0355 {
0356     int i;
0357     unsigned long flags;
0358     struct opl4_voice *voice;
0359 
0360     spin_lock_irqsave(&opl4->reg_lock, flags);
0361     for (i = 0; i < OPL4_MAX_VOICES; i++) {
0362         voice = &opl4->voices[i];
0363         if (voice->chan)
0364             func(opl4, voice);
0365     }
0366     spin_unlock_irqrestore(&opl4->reg_lock, flags);
0367 }
0368 
0369 static void snd_opl4_update_volume(struct snd_opl4 *opl4, struct opl4_voice *voice)
0370 {
0371     int att;
0372 
0373     att = voice->sound->tone_attenuate;
0374     att += snd_opl4_volume_table[opl4->chset->gs_master_volume & 0x7f];
0375     att += snd_opl4_volume_table[voice->chan->gm_volume & 0x7f];
0376     att += snd_opl4_volume_table[voice->chan->gm_expression & 0x7f];
0377     att += snd_opl4_volume_table[voice->velocity];
0378     att = 0x7f - (0x7f - att) * (voice->sound->volume_factor) / 0xfe - volume_boost;
0379     if (att < 0)
0380         att = 0;
0381     else if (att > 0x7e)
0382         att = 0x7e;
0383     snd_opl4_write(opl4, OPL4_REG_LEVEL + voice->number,
0384                (att << 1) | voice->level_direct);
0385     voice->level_direct = 0;
0386 }
0387 
0388 static void snd_opl4_update_pan(struct snd_opl4 *opl4, struct opl4_voice *voice)
0389 {
0390     int pan = voice->sound->panpot;
0391 
0392     if (!voice->chan->drum_channel)
0393         pan += (voice->chan->control[MIDI_CTL_MSB_PAN] - 0x40) >> 3;
0394     if (pan < -7)
0395         pan = -7;
0396     else if (pan > 7)
0397         pan = 7;
0398     voice->reg_misc = (voice->reg_misc & ~OPL4_PAN_POT_MASK)
0399         | (pan & OPL4_PAN_POT_MASK);
0400     snd_opl4_write(opl4, OPL4_REG_MISC + voice->number, voice->reg_misc);
0401 }
0402 
0403 static void snd_opl4_update_vibrato_depth(struct snd_opl4 *opl4,
0404                       struct opl4_voice *voice)
0405 {
0406     int depth;
0407 
0408     if (voice->chan->drum_channel)
0409         return;
0410     depth = (7 - voice->sound->vibrato)
0411         * (voice->chan->control[MIDI_CTL_VIBRATO_DEPTH] & 0x7f);
0412     depth = (depth >> 7) + voice->sound->vibrato;
0413     voice->reg_lfo_vibrato &= ~OPL4_VIBRATO_DEPTH_MASK;
0414     voice->reg_lfo_vibrato |= depth & OPL4_VIBRATO_DEPTH_MASK;
0415     snd_opl4_write(opl4, OPL4_REG_LFO_VIBRATO + voice->number,
0416                voice->reg_lfo_vibrato);
0417 }
0418 
0419 static void snd_opl4_update_pitch(struct snd_opl4 *opl4,
0420                   struct opl4_voice *voice)
0421 {
0422     struct snd_midi_channel *chan = voice->chan;
0423     int note, pitch, octave;
0424 
0425     note = chan->drum_channel ? 60 : voice->note;
0426     /*
0427      * pitch is in 100/128 cents, so 0x80 is one semitone and
0428      * 0x600 is one octave.
0429      */
0430     pitch = ((note - 60) << 7) * voice->sound->key_scaling / 100 + (60 << 7);
0431     pitch += voice->sound->pitch_offset;
0432     if (!chan->drum_channel)
0433         pitch += chan->gm_rpn_coarse_tuning;
0434     pitch += chan->gm_rpn_fine_tuning >> 7;
0435     pitch += chan->midi_pitchbend * chan->gm_rpn_pitch_bend_range / 0x2000;
0436     if (pitch < 0)
0437         pitch = 0;
0438     else if (pitch >= 0x6000)
0439         pitch = 0x5fff;
0440     octave = pitch / 0x600 - 8;
0441     pitch = snd_opl4_pitch_map[pitch % 0x600];
0442 
0443     snd_opl4_write(opl4, OPL4_REG_OCTAVE + voice->number,
0444                (octave << 4) | ((pitch >> 7) & OPL4_F_NUMBER_HIGH_MASK));
0445     voice->reg_f_number = (voice->reg_f_number & OPL4_TONE_NUMBER_BIT8)
0446         | ((pitch << 1) & OPL4_F_NUMBER_LOW_MASK);
0447     snd_opl4_write(opl4, OPL4_REG_F_NUMBER + voice->number, voice->reg_f_number);
0448 }
0449 
0450 static void snd_opl4_update_tone_parameters(struct snd_opl4 *opl4,
0451                         struct opl4_voice *voice)
0452 {
0453     snd_opl4_write(opl4, OPL4_REG_ATTACK_DECAY1 + voice->number,
0454                voice->sound->reg_attack_decay1);
0455     snd_opl4_write(opl4, OPL4_REG_LEVEL_DECAY2 + voice->number,
0456                voice->sound->reg_level_decay2);
0457     snd_opl4_write(opl4, OPL4_REG_RELEASE_CORRECTION + voice->number,
0458                voice->sound->reg_release_correction);
0459     snd_opl4_write(opl4, OPL4_REG_TREMOLO + voice->number,
0460                voice->sound->reg_tremolo);
0461 }
0462 
0463 /* allocate one voice */
0464 static struct opl4_voice *snd_opl4_get_voice(struct snd_opl4 *opl4)
0465 {
0466     /* first, try to get the oldest key-off voice */
0467     if (!list_empty(&opl4->off_voices))
0468         return list_entry(opl4->off_voices.next, struct opl4_voice, list);
0469     /* then get the oldest key-on voice */
0470     snd_BUG_ON(list_empty(&opl4->on_voices));
0471     return list_entry(opl4->on_voices.next, struct opl4_voice, list);
0472 }
0473 
0474 static void snd_opl4_wait_for_wave_headers(struct snd_opl4 *opl4)
0475 {
0476     int timeout = 200;
0477 
0478     while ((inb(opl4->fm_port) & OPL4_STATUS_LOAD) && --timeout > 0)
0479         udelay(10);
0480 }
0481 
0482 void snd_opl4_note_on(void *private_data, int note, int vel, struct snd_midi_channel *chan)
0483 {
0484     struct snd_opl4 *opl4 = private_data;
0485     const struct opl4_region_ptr *regions;
0486     struct opl4_voice *voice[2];
0487     const struct opl4_sound *sound[2];
0488     int voices = 0, i;
0489     unsigned long flags;
0490 
0491     /* determine the number of voices and voice parameters */
0492     i = chan->drum_channel ? 0x80 : (chan->midi_program & 0x7f);
0493     regions = &snd_yrw801_regions[i];
0494     for (i = 0; i < regions->count; i++) {
0495         if (note >= regions->regions[i].key_min &&
0496             note <= regions->regions[i].key_max) {
0497             sound[voices] = &regions->regions[i].sound;
0498             if (++voices >= 2)
0499                 break;
0500         }
0501     }
0502 
0503     /* allocate and initialize the needed voices */
0504     spin_lock_irqsave(&opl4->reg_lock, flags);
0505     for (i = 0; i < voices; i++) {
0506         voice[i] = snd_opl4_get_voice(opl4);
0507         list_move_tail(&voice[i]->list, &opl4->on_voices);
0508         voice[i]->chan = chan;
0509         voice[i]->note = note;
0510         voice[i]->velocity = vel & 0x7f;
0511         voice[i]->sound = sound[i];
0512     }
0513 
0514     /* set tone number (triggers header loading) */
0515     for (i = 0; i < voices; i++) {
0516         voice[i]->reg_f_number =
0517             (sound[i]->tone >> 8) & OPL4_TONE_NUMBER_BIT8;
0518         snd_opl4_write(opl4, OPL4_REG_F_NUMBER + voice[i]->number,
0519                    voice[i]->reg_f_number);
0520         snd_opl4_write(opl4, OPL4_REG_TONE_NUMBER + voice[i]->number,
0521                    sound[i]->tone & 0xff);
0522     }
0523 
0524     /* set parameters which can be set while loading */
0525     for (i = 0; i < voices; i++) {
0526         voice[i]->reg_misc = OPL4_LFO_RESET_BIT;
0527         snd_opl4_update_pan(opl4, voice[i]);
0528         snd_opl4_update_pitch(opl4, voice[i]);
0529         voice[i]->level_direct = OPL4_LEVEL_DIRECT_BIT;
0530         snd_opl4_update_volume(opl4, voice[i]);
0531     }
0532     spin_unlock_irqrestore(&opl4->reg_lock, flags);
0533 
0534     /* wait for completion of loading */
0535     snd_opl4_wait_for_wave_headers(opl4);
0536 
0537     /* set remaining parameters */
0538     spin_lock_irqsave(&opl4->reg_lock, flags);
0539     for (i = 0; i < voices; i++) {
0540         snd_opl4_update_tone_parameters(opl4, voice[i]);
0541         voice[i]->reg_lfo_vibrato = voice[i]->sound->reg_lfo_vibrato;
0542         snd_opl4_update_vibrato_depth(opl4, voice[i]);
0543     }
0544 
0545     /* finally, switch on all voices */
0546     for (i = 0; i < voices; i++) {
0547         voice[i]->reg_misc =
0548             (voice[i]->reg_misc & 0x1f) | OPL4_KEY_ON_BIT;
0549         snd_opl4_write(opl4, OPL4_REG_MISC + voice[i]->number,
0550                    voice[i]->reg_misc);
0551     }
0552     spin_unlock_irqrestore(&opl4->reg_lock, flags);
0553 }
0554 
0555 static void snd_opl4_voice_off(struct snd_opl4 *opl4, struct opl4_voice *voice)
0556 {
0557     list_move_tail(&voice->list, &opl4->off_voices);
0558 
0559     voice->reg_misc &= ~OPL4_KEY_ON_BIT;
0560     snd_opl4_write(opl4, OPL4_REG_MISC + voice->number, voice->reg_misc);
0561 }
0562 
0563 void snd_opl4_note_off(void *private_data, int note, int vel, struct snd_midi_channel *chan)
0564 {
0565     struct snd_opl4 *opl4 = private_data;
0566 
0567     snd_opl4_do_for_note(opl4, note, chan, snd_opl4_voice_off);
0568 }
0569 
0570 static void snd_opl4_terminate_voice(struct snd_opl4 *opl4, struct opl4_voice *voice)
0571 {
0572     list_move_tail(&voice->list, &opl4->off_voices);
0573 
0574     voice->reg_misc = (voice->reg_misc & ~OPL4_KEY_ON_BIT) | OPL4_DAMP_BIT;
0575     snd_opl4_write(opl4, OPL4_REG_MISC + voice->number, voice->reg_misc);
0576 }
0577 
0578 void snd_opl4_terminate_note(void *private_data, int note, struct snd_midi_channel *chan)
0579 {
0580     struct snd_opl4 *opl4 = private_data;
0581 
0582     snd_opl4_do_for_note(opl4, note, chan, snd_opl4_terminate_voice);
0583 }
0584 
0585 void snd_opl4_control(void *private_data, int type, struct snd_midi_channel *chan)
0586 {
0587     struct snd_opl4 *opl4 = private_data;
0588 
0589     switch (type) {
0590     case MIDI_CTL_MSB_MODWHEEL:
0591         chan->control[MIDI_CTL_VIBRATO_DEPTH] = chan->control[MIDI_CTL_MSB_MODWHEEL];
0592         snd_opl4_do_for_channel(opl4, chan, snd_opl4_update_vibrato_depth);
0593         break;
0594     case MIDI_CTL_MSB_MAIN_VOLUME:
0595         snd_opl4_do_for_channel(opl4, chan, snd_opl4_update_volume);
0596         break;
0597     case MIDI_CTL_MSB_PAN:
0598         snd_opl4_do_for_channel(opl4, chan, snd_opl4_update_pan);
0599         break;
0600     case MIDI_CTL_MSB_EXPRESSION:
0601         snd_opl4_do_for_channel(opl4, chan, snd_opl4_update_volume);
0602         break;
0603     case MIDI_CTL_VIBRATO_RATE:
0604         /* not yet supported */
0605         break;
0606     case MIDI_CTL_VIBRATO_DEPTH:
0607         snd_opl4_do_for_channel(opl4, chan, snd_opl4_update_vibrato_depth);
0608         break;
0609     case MIDI_CTL_VIBRATO_DELAY:
0610         /* not yet supported */
0611         break;
0612     case MIDI_CTL_E1_REVERB_DEPTH:
0613         /*
0614          * Each OPL4 voice has a bit called "Pseudo-Reverb", but
0615          * IMHO _not_ using it enhances the listening experience.
0616          */
0617         break;
0618     case MIDI_CTL_PITCHBEND:
0619         snd_opl4_do_for_channel(opl4, chan, snd_opl4_update_pitch);
0620         break;
0621     }
0622 }
0623 
0624 void snd_opl4_sysex(void *private_data, unsigned char *buf, int len,
0625             int parsed, struct snd_midi_channel_set *chset)
0626 {
0627     struct snd_opl4 *opl4 = private_data;
0628 
0629     if (parsed == SNDRV_MIDI_SYSEX_GS_MASTER_VOLUME)
0630         snd_opl4_do_for_all(opl4, snd_opl4_update_volume);
0631 }