0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034 #include "opl4_local.h"
0035 #include <linux/delay.h>
0036 #include <linux/io.h>
0037 #include <sound/asoundef.h>
0038
0039
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
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
0249
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
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
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
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
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
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
0428
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
0464 static struct opl4_voice *snd_opl4_get_voice(struct snd_opl4 *opl4)
0465 {
0466
0467 if (!list_empty(&opl4->off_voices))
0468 return list_entry(opl4->off_voices.next, struct opl4_voice, list);
0469
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
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] = ®ions->regions[i].sound;
0498 if (++voices >= 2)
0499 break;
0500 }
0501 }
0502
0503
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
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
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
0535 snd_opl4_wait_for_wave_headers(opl4);
0536
0537
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
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
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
0611 break;
0612 case MIDI_CTL_E1_REVERB_DEPTH:
0613
0614
0615
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 }