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