~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/sound/drivers/opl4/opl4_synth.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  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  */
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  */
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  */
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  */
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  */
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 
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 
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 
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 
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 
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 */
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 
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 
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 
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 
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 
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 
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 
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 
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 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php