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

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

Version: ~ [ linux-5.0-rc6 ] ~ [ linux-4.20.10 ] ~ [ linux-4.19.23 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.101 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.158 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.174 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.134 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.63 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-3.9.11 ] ~ [ linux-3.8.13 ] ~ [ linux-3.7.10 ] ~ [ linux-3.6.11 ] ~ [ linux-3.5.7 ] ~ [ linux-3.4.113 ] ~ [ linux-3.3.8 ] ~ [ linux-3.2.102 ] ~ [ linux-3.1.10 ] ~ [ linux-3.0.101 ] ~ [ linux-2.6.39.4 ] ~ [ linux-2.6.38.8 ] ~ [ linux-2.6.37.6 ] ~ [ linux-2.6.36.4 ] ~ [ linux-2.6.35.14 ] ~ [ linux-2.6.34.15 ] ~ [ linux-2.6.33.20 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ 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 <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  */
 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 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(opl4_t *opl4)
274 {
275         int i;
276 
277         for (i = 0; i < OPL4_MAX_VOICES; i++)
278                 snd_opl4_write(opl4, OPL4_REG_MISC + i, OPL4_DAMP_BIT);
279 
280         spin_lock_init(&opl4->voices_lock);
281         INIT_LIST_HEAD(&opl4->off_voices);
282         INIT_LIST_HEAD(&opl4->on_voices);
283         memset(opl4->voices, 0, sizeof(opl4->voices));
284         for (i = 0; i < OPL4_MAX_VOICES; i++) {
285                 opl4->voices[i].number = i;
286                 list_add_tail(&opl4->voices[i].list, &opl4->off_voices);
287         }
288 
289         snd_midi_channel_set_clear(opl4->chset);
290 }
291 
292 /*
293  * Shuts down all voices.
294  */
295 void snd_opl4_synth_shutdown(opl4_t *opl4)
296 {
297         int i;
298 
299         for (i = 0; i < OPL4_MAX_VOICES; i++)
300                 snd_opl4_write(opl4, OPL4_REG_MISC + i,
301                                opl4->voices[i].reg_misc & ~OPL4_KEY_ON_BIT);
302 }
303 
304 /*
305  * Executes the callback for all voices playing the specified note.
306  */
307 static void snd_opl4_do_for_note(opl4_t *opl4, int note, snd_midi_channel_t *chan,
308                                  void (*func)(opl4_t *opl4, opl4_voice_t *voice))
309 {
310         int i;
311         unsigned long flags;
312         opl4_voice_t *voice;
313 
314         spin_lock_irqsave(&opl4->voices_lock, flags);
315         for (i = 0; i < OPL4_MAX_VOICES; i++) {
316                 voice = &opl4->voices[i];
317                 if (voice->chan == chan && voice->note == note) {
318                         func(opl4, voice);
319                 }
320         }
321         spin_unlock_irqrestore(&opl4->voices_lock, flags);
322 }
323 
324 /*
325  * Executes the callback for all voices of to the specified channel.
326  */
327 static void snd_opl4_do_for_channel(opl4_t *opl4, snd_midi_channel_t *chan,
328                                     void (*func)(opl4_t *opl4, opl4_voice_t *voice))
329 {
330         int i;
331         unsigned long flags;
332         opl4_voice_t *voice;
333 
334         spin_lock_irqsave(&opl4->voices_lock, flags);
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         spin_unlock_irqrestore(&opl4->voices_lock, flags);
342 }
343 
344 /*
345  * Executes the callback for all active voices.
346  */
347 static void snd_opl4_do_for_all(opl4_t *opl4,
348                                 void (*func)(opl4_t *opl4, opl4_voice_t *voice))
349 {
350         int i;
351         unsigned long flags;
352         opl4_voice_t *voice;
353 
354         spin_lock_irqsave(&opl4->voices_lock, flags);
355         for (i = 0; i < OPL4_MAX_VOICES; i++) {
356                 voice = &opl4->voices[i];
357                 if (voice->chan)
358                         func(opl4, voice);
359         }
360         spin_unlock_irqrestore(&opl4->voices_lock, flags);
361 }
362 
363 static void snd_opl4_update_volume(opl4_t *opl4, opl4_voice_t *voice)
364 {
365         int att;
366 
367         att = voice->sound->tone_attenuate;
368         att += snd_opl4_volume_table[opl4->chset->gs_master_volume & 0x7f];
369         att += snd_opl4_volume_table[voice->chan->gm_volume & 0x7f];
370         att += snd_opl4_volume_table[voice->chan->gm_expression & 0x7f];
371         att += snd_opl4_volume_table[voice->velocity];
372         att = 0x7f - (0x7f - att) * (voice->sound->volume_factor) / 0xfe - volume_boost;
373         if (att < 0)
374                 att = 0;
375         else if (att > 0x7e)
376                 att = 0x7e;
377         snd_opl4_write(opl4, OPL4_REG_LEVEL + voice->number,
378                        (att << 1) | voice->level_direct);
379         voice->level_direct = 0;
380 }
381 
382 static void snd_opl4_update_pan(opl4_t *opl4, opl4_voice_t *voice)
383 {
384         int pan = voice->sound->panpot;
385 
386         if (!voice->chan->drum_channel)
387                 pan += (voice->chan->control[MIDI_CTL_MSB_PAN] - 0x40) >> 3;
388         if (pan < -7)
389                 pan = -7;
390         else if (pan > 7)
391                 pan = 7;
392         voice->reg_misc = (voice->reg_misc & ~OPL4_PAN_POT_MASK)
393                 | (pan & OPL4_PAN_POT_MASK);
394         snd_opl4_write(opl4, OPL4_REG_MISC + voice->number, voice->reg_misc);
395 }
396 
397 static void snd_opl4_update_vibrato_depth(opl4_t *opl4, opl4_voice_t *voice)
398 {
399         int depth;
400 
401         if (voice->chan->drum_channel)
402                 return;
403         depth = (7 - voice->sound->vibrato)
404                 * (voice->chan->control[MIDI_CTL_VIBRATO_DEPTH] & 0x7f);
405         depth = (depth >> 7) + voice->sound->vibrato;
406         voice->reg_lfo_vibrato &= ~OPL4_VIBRATO_DEPTH_MASK;
407         voice->reg_lfo_vibrato |= depth & OPL4_VIBRATO_DEPTH_MASK;
408         snd_opl4_write(opl4, OPL4_REG_LFO_VIBRATO + voice->number,
409                        voice->reg_lfo_vibrato);
410 }
411 
412 static void snd_opl4_update_pitch(opl4_t *opl4, opl4_voice_t *voice)
413 {
414         snd_midi_channel_t *chan = voice->chan;
415         int note, pitch, octave;
416 
417         note = chan->drum_channel ? 60 : voice->note;
418         /*
419          * pitch is in 100/128 cents, so 0x80 is one semitone and
420          * 0x600 is one octave.
421          */
422         pitch = ((note - 60) << 7) * voice->sound->key_scaling / 100 + (60 << 7);
423         pitch += voice->sound->pitch_offset;
424         if (!chan->drum_channel)
425                 pitch += chan->gm_rpn_coarse_tuning;
426         pitch += chan->gm_rpn_fine_tuning >> 7;
427         pitch += chan->midi_pitchbend * chan->gm_rpn_pitch_bend_range / 0x2000;
428         if (pitch < 0)
429                 pitch = 0;
430         else if (pitch >= 0x6000)
431                 pitch = 0x5fff;
432         octave = pitch / 0x600 - 8;
433         pitch = snd_opl4_pitch_map[pitch % 0x600];
434 
435         snd_opl4_write(opl4, OPL4_REG_OCTAVE + voice->number,
436                        (octave << 4) | ((pitch >> 7) & OPL4_F_NUMBER_HIGH_MASK));
437         voice->reg_f_number = (voice->reg_f_number & OPL4_TONE_NUMBER_BIT8)
438                 | ((pitch << 1) & OPL4_F_NUMBER_LOW_MASK);
439         snd_opl4_write(opl4, OPL4_REG_F_NUMBER + voice->number, voice->reg_f_number);
440 }
441 
442 static void snd_opl4_update_tone_parameters(opl4_t *opl4, opl4_voice_t *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 opl4_voice_t *snd_opl4_get_voice(opl4_t *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, opl4_voice_t, list);
460         /* then get the oldest key-on voice */
461         snd_assert(!list_empty(&opl4->on_voices), );
462         return list_entry(opl4->on_voices.next, opl4_voice_t, list);
463 }
464 
465 static void snd_opl4_wait_for_wave_headers(opl4_t *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, snd_midi_channel_t *chan)
474 {
475         opl4_t *opl4 = snd_magic_cast(opl4_t, private_data, return);
476         const opl4_region_ptr_t *regions;
477         opl4_voice_t *voice[2];
478         const opl4_sound_t *sound[2];
479         int voices = 0, i;
480         unsigned long flags;
481 
482         /* determine the number of voices and voice parameters */
483         i = chan->drum_channel ? 0x80 : (chan->midi_program & 0x7f);
484         regions = &snd_yrw801_regions[i];
485         for (i = 0; i < regions->count; i++) {
486                 if (note >= regions->regions[i].key_min &&
487                     note <= regions->regions[i].key_max) {
488                         sound[voices] = &regions->regions[i].sound;
489                         if (++voices >= 2)
490                                 break;
491                 }
492         }
493 
494         /* allocate and initialize the needed voices */
495         spin_lock_irqsave(&opl4->voices_lock, flags);
496         for (i = 0; i < voices; i++) {
497                 voice[i] = snd_opl4_get_voice(opl4);
498                 list_del(&voice[i]->list);
499                 list_add_tail(&voice[i]->list, &opl4->on_voices);
500                 voice[i]->chan = chan;
501                 voice[i]->note = note;
502                 voice[i]->velocity = vel & 0x7f;
503                 voice[i]->sound = sound[i];
504         }
505         spin_unlock_irqrestore(&opl4->voices_lock, flags);
506 
507         /* set tone number (triggers header loading) */
508         for (i = 0; i < voices; i++) {
509                 voice[i]->reg_f_number =
510                         (sound[i]->tone >> 8) & OPL4_TONE_NUMBER_BIT8;
511                 snd_opl4_write(opl4, OPL4_REG_F_NUMBER + voice[i]->number,
512                                voice[i]->reg_f_number);
513                 snd_opl4_write(opl4, OPL4_REG_TONE_NUMBER + voice[i]->number,
514                                sound[i]->tone & 0xff);
515         }
516 
517         /* set parameters which can be set while loading */
518         for (i = 0; i < voices; i++) {
519                 voice[i]->reg_misc = OPL4_LFO_RESET_BIT;
520                 snd_opl4_update_pan(opl4, voice[i]);
521                 snd_opl4_update_pitch(opl4, voice[i]);
522                 voice[i]->level_direct = OPL4_LEVEL_DIRECT_BIT;
523                 snd_opl4_update_volume(opl4, voice[i]);
524         }
525 
526         /* wait for completion of loading */
527         snd_opl4_wait_for_wave_headers(opl4);
528 
529         /* set remaining parameters */
530         for (i = 0; i < voices; i++) {
531                 snd_opl4_update_tone_parameters(opl4, voice[i]);
532                 voice[i]->reg_lfo_vibrato = voice[i]->sound->reg_lfo_vibrato;
533                 snd_opl4_update_vibrato_depth(opl4, voice[i]);
534         }
535 
536         /* finally, switch on all voices */
537         for (i = 0; i < voices; i++) {
538                 voice[i]->reg_misc =
539                         (voice[i]->reg_misc & 0x1f) | OPL4_KEY_ON_BIT;
540                 snd_opl4_write(opl4, OPL4_REG_MISC + voice[i]->number,
541                                voice[i]->reg_misc);
542         }
543 }
544 
545 static void snd_opl4_voice_off(opl4_t *opl4, opl4_voice_t *voice)
546 {
547         list_del(&voice->list);
548         list_add_tail(&voice->list, &opl4->off_voices);
549 
550         voice->reg_misc &= ~OPL4_KEY_ON_BIT;
551         snd_opl4_write(opl4, OPL4_REG_MISC + voice->number, voice->reg_misc);
552 }
553 
554 void snd_opl4_note_off(void *private_data, int note, int vel, snd_midi_channel_t *chan)
555 {
556         opl4_t *opl4 = snd_magic_cast(opl4_t, private_data, return);
557 
558         snd_opl4_do_for_note(opl4, note, chan, snd_opl4_voice_off);
559 }
560 
561 static void snd_opl4_terminate_voice(opl4_t *opl4, opl4_voice_t *voice)
562 {
563         list_del(&voice->list);
564         list_add_tail(&voice->list, &opl4->off_voices);
565 
566         voice->reg_misc = (voice->reg_misc & ~OPL4_KEY_ON_BIT) | OPL4_DAMP_BIT;
567         snd_opl4_write(opl4, OPL4_REG_MISC + voice->number, voice->reg_misc);
568 }
569 
570 void snd_opl4_terminate_note(void *private_data, int note, snd_midi_channel_t *chan)
571 {
572         opl4_t *opl4 = snd_magic_cast(opl4_t, private_data, return);
573 
574         snd_opl4_do_for_note(opl4, note, chan, snd_opl4_terminate_voice);
575 }
576 
577 void snd_opl4_control(void *private_data, int type, snd_midi_channel_t *chan)
578 {
579         opl4_t *opl4 = snd_magic_cast(opl4_t, private_data, return);
580 
581         switch (type) {
582         case MIDI_CTL_MSB_MODWHEEL:
583                 chan->control[MIDI_CTL_VIBRATO_DEPTH] = chan->control[MIDI_CTL_MSB_MODWHEEL];
584                 snd_opl4_do_for_channel(opl4, chan, snd_opl4_update_vibrato_depth);
585                 break;
586         case MIDI_CTL_MSB_MAIN_VOLUME:
587                 snd_opl4_do_for_channel(opl4, chan, snd_opl4_update_volume);
588                 break;
589         case MIDI_CTL_MSB_PAN:
590                 snd_opl4_do_for_channel(opl4, chan, snd_opl4_update_pan);
591                 break;
592         case MIDI_CTL_MSB_EXPRESSION:
593                 snd_opl4_do_for_channel(opl4, chan, snd_opl4_update_volume);
594                 break;
595         case MIDI_CTL_VIBRATO_RATE:
596                 /* not yet supported */
597                 break;
598         case MIDI_CTL_VIBRATO_DEPTH:
599                 snd_opl4_do_for_channel(opl4, chan, snd_opl4_update_vibrato_depth);
600                 break;
601         case MIDI_CTL_VIBRATO_DELAY:
602                 /* not yet supported */
603                 break;
604         case MIDI_CTL_E1_REVERB_DEPTH:
605                 /*
606                  * Each OPL4 voice has a bit called "Pseudo-Reverb", but
607                  * IMHO _not_ using it enhances the listening experience.
608                  */
609                 break;
610         case MIDI_CTL_PITCHBEND:
611                 snd_opl4_do_for_channel(opl4, chan, snd_opl4_update_pitch);
612                 break;
613         }
614 }
615 
616 void snd_opl4_sysex(void *private_data, unsigned char *buf, int len,
617                     int parsed, snd_midi_channel_set_t *chset)
618 {
619         opl4_t *opl4 = snd_magic_cast(opl4_t, private_data, return);
620 
621         if (parsed == SNDRV_MIDI_SYSEX_GS_MASTER_VOLUME)
622                 snd_opl4_do_for_all(opl4, snd_opl4_update_volume);
623 }
624 

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

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | 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.

osdn.jp