xref: /openbmc/linux/sound/drivers/opl4/opl4_synth.c (revision 1d99500a)
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  */
52 static 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  */
251 static 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  */
snd_opl4_synth_reset(struct snd_opl4 * opl4)273 void 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  */
snd_opl4_synth_shutdown(struct snd_opl4 * opl4)297 void 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  */
snd_opl4_do_for_note(struct snd_opl4 * opl4,int note,struct snd_midi_channel * chan,void (* func)(struct snd_opl4 * opl4,struct opl4_voice * voice))312 static 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  */
snd_opl4_do_for_channel(struct snd_opl4 * opl4,struct snd_midi_channel * chan,void (* func)(struct snd_opl4 * opl4,struct opl4_voice * voice))332 static 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  */
snd_opl4_do_for_all(struct snd_opl4 * opl4,void (* func)(struct snd_opl4 * opl4,struct opl4_voice * voice))353 static 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 
snd_opl4_update_volume(struct snd_opl4 * opl4,struct opl4_voice * voice)369 static 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 
snd_opl4_update_pan(struct snd_opl4 * opl4,struct opl4_voice * voice)388 static 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 
snd_opl4_update_vibrato_depth(struct snd_opl4 * opl4,struct opl4_voice * voice)403 static 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 
snd_opl4_update_pitch(struct snd_opl4 * opl4,struct opl4_voice * voice)419 static 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 
snd_opl4_update_tone_parameters(struct snd_opl4 * opl4,struct opl4_voice * voice)450 static 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 */
snd_opl4_get_voice(struct snd_opl4 * opl4)464 static 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 
snd_opl4_wait_for_wave_headers(struct snd_opl4 * opl4)474 static 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 
snd_opl4_note_on(void * private_data,int note,int vel,struct snd_midi_channel * chan)482 void 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 
snd_opl4_voice_off(struct snd_opl4 * opl4,struct opl4_voice * voice)555 static 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 
snd_opl4_note_off(void * private_data,int note,int vel,struct snd_midi_channel * chan)563 void 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 
snd_opl4_terminate_voice(struct snd_opl4 * opl4,struct opl4_voice * voice)570 static 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 
snd_opl4_terminate_note(void * private_data,int note,struct snd_midi_channel * chan)578 void 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 
snd_opl4_control(void * private_data,int type,struct snd_midi_channel * chan)585 void 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 
snd_opl4_sysex(void * private_data,unsigned char * buf,int len,int parsed,struct snd_midi_channel_set * chset)624 void 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 }
632