Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/sound/drivers/opl4/opl4_synth.c
29266 views
1
/*
2
* OPL4 MIDI synthesizer functions
3
*
4
* Copyright (c) 2003 by Clemens Ladisch <[email protected]>
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
*/
273
void 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
*/
296
void 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
*/
309
static 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
*/
327
static 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
*/
346
static 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
360
static 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
379
static 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
394
static 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
410
static 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
441
static 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 */
455
static 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
465
static 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
473
void 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
544
static 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
552
void 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
559
static 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
567
void 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
574
void 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
613
void 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
}
621
622