File Index
Files and directories
Sign in
FILE

opl4_synth.c

File preview with syntax highlighting.

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