YM2151.java
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52: package xeij;
53:
54: import java.io.*;
55: import java.nio.*;
56: import java.util.*;
57:
58: public class YM2151 {
59:
60:
61:
62: public static int sint8 (int x) {
63: return (byte) x;
64: }
65: public static int sint16 (int x) {
66: return (short) x;
67: }
68: public static int uint8 (int x) {
69: return 0xff & x;
70: }
71: public static int uint16 (int x) {
72: return (char) x;
73: }
74: public static int umin32 (int x, int y) {
75: return Integer.compareUnsigned (x, y) < 0 ? x : y;
76: }
77:
78:
79:
80:
81:
82:
83:
84:
85: public static int bitfield ( int value, int start) {
86: return (value >>> start) & 1;
87: }
88: public static int bitfield ( int value, int start, int length) {
89: return (value >>> start) & ((1 << length) - 1);
90: }
91:
92:
93:
94:
95:
96: public static int clamp ( int value, int minval, int maxval) {
97:
98: if (value < minval) {
99: return minval;
100: }
101: if (value > maxval) {
102: return maxval;
103: }
104: return value;
105: }
106:
107:
108:
109:
110:
111:
112:
113: public static int count_leading_zeros ( int value) {
114:
115: if (value == 0) {
116: return 32;
117: }
118: int count;
119: for (count = 0; value >= 0; count++) {
120: value <<= 1;
121: }
122: return count;
123: }
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152: public static int roundtrip_fp ( int value) {
153:
154: if (value < -32768) {
155: return sint16 (-32768);
156: }
157: if (value > 32767) {
158: return sint16 (32767);
159: }
160:
161:
162:
163: int scanvalue = value ^ (value >> 31);
164:
165:
166: int exponent = 7 - count_leading_zeros (scanvalue << 17);
167:
168:
169: exponent = Math.max (exponent, 1);
170:
171:
172: exponent -= 1;
173: return sint16 ((value >> exponent) << exponent);
174: }
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
199: public static final int OUTPUTS = 2;
200: public static final int CHANNELS = 8;
201: public static final int ALL_CHANNELS = (1 << CHANNELS) - 1;
202: public static final int OPERATORS = CHANNELS * 4;
203: public static final int WAVEFORMS = 1;
204: public static final int REGISTERS = 0x100;
205: public static final int DEFAULT_PRESCALE = 2;
206: public static final int EG_CLOCK_DIVIDER = 3;
207: public static final int CSM_TRIGGER_MASK = ALL_CHANNELS;
208: public static final int REG_MODE = 0x14;
209: public static final int STATUS_TIMERA = 0x01;
210: public static final int STATUS_TIMERB = 0x02;
211: public static final int STATUS_BUSY = 0x80;
212: public static final int STATUS_IRQ = 0;
213:
214:
215:
216: public static final int EG_ATTACK = 1;
217: public static final int EG_DECAY = 2;
218: public static final int EG_SUSTAIN = 3;
219: public static final int EG_RELEASE = 4;
220: public static final int EG_STATES = 6;
221:
222:
223:
224:
225:
226:
227:
228: public static final int WAVEFORM_LENGTH = 0x400;
229:
230:
231:
232:
233: public static final int PHASE_STEP_DYNAMIC = 1;
234:
235:
236: public static final int EG_QUIET = 0x380;
237:
238:
239:
240: public static final int[] s_sin_table = {
241: 0x859, 0x6c3, 0x607, 0x58b, 0x52e, 0x4e4, 0x4a6, 0x471, 0x443, 0x41a, 0x3f5, 0x3d3, 0x3b5, 0x398, 0x37e, 0x365,
242: 0x34e, 0x339, 0x324, 0x311, 0x2ff, 0x2ed, 0x2dc, 0x2cd, 0x2bd, 0x2af, 0x2a0, 0x293, 0x286, 0x279, 0x26d, 0x261,
243: 0x256, 0x24b, 0x240, 0x236, 0x22c, 0x222, 0x218, 0x20f, 0x206, 0x1fd, 0x1f5, 0x1ec, 0x1e4, 0x1dc, 0x1d4, 0x1cd,
244: 0x1c5, 0x1be, 0x1b7, 0x1b0, 0x1a9, 0x1a2, 0x19b, 0x195, 0x18f, 0x188, 0x182, 0x17c, 0x177, 0x171, 0x16b, 0x166,
245: 0x160, 0x15b, 0x155, 0x150, 0x14b, 0x146, 0x141, 0x13c, 0x137, 0x133, 0x12e, 0x129, 0x125, 0x121, 0x11c, 0x118,
246: 0x114, 0x10f, 0x10b, 0x107, 0x103, 0x0ff, 0x0fb, 0x0f8, 0x0f4, 0x0f0, 0x0ec, 0x0e9, 0x0e5, 0x0e2, 0x0de, 0x0db,
247: 0x0d7, 0x0d4, 0x0d1, 0x0cd, 0x0ca, 0x0c7, 0x0c4, 0x0c1, 0x0be, 0x0bb, 0x0b8, 0x0b5, 0x0b2, 0x0af, 0x0ac, 0x0a9,
248: 0x0a7, 0x0a4, 0x0a1, 0x09f, 0x09c, 0x099, 0x097, 0x094, 0x092, 0x08f, 0x08d, 0x08a, 0x088, 0x086, 0x083, 0x081,
249: 0x07f, 0x07d, 0x07a, 0x078, 0x076, 0x074, 0x072, 0x070, 0x06e, 0x06c, 0x06a, 0x068, 0x066, 0x064, 0x062, 0x060,
250: 0x05e, 0x05c, 0x05b, 0x059, 0x057, 0x055, 0x053, 0x052, 0x050, 0x04e, 0x04d, 0x04b, 0x04a, 0x048, 0x046, 0x045,
251: 0x043, 0x042, 0x040, 0x03f, 0x03e, 0x03c, 0x03b, 0x039, 0x038, 0x037, 0x035, 0x034, 0x033, 0x031, 0x030, 0x02f,
252: 0x02e, 0x02d, 0x02b, 0x02a, 0x029, 0x028, 0x027, 0x026, 0x025, 0x024, 0x023, 0x022, 0x021, 0x020, 0x01f, 0x01e,
253: 0x01d, 0x01c, 0x01b, 0x01a, 0x019, 0x018, 0x017, 0x017, 0x016, 0x015, 0x014, 0x014, 0x013, 0x012, 0x011, 0x011,
254: 0x010, 0x00f, 0x00f, 0x00e, 0x00d, 0x00d, 0x00c, 0x00c, 0x00b, 0x00a, 0x00a, 0x009, 0x009, 0x008, 0x008, 0x007,
255: 0x007, 0x007, 0x006, 0x006, 0x005, 0x005, 0x005, 0x004, 0x004, 0x004, 0x003, 0x003, 0x003, 0x002, 0x002, 0x002,
256: 0x002, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
257: };
258:
259: private static int X (int a) {
260: return (a | 0x400) << 2;
261: }
262: public static final int[] s_power_table = {
263: X (0x3fa), X (0x3f5), X (0x3ef), X (0x3ea), X (0x3e4), X (0x3df), X (0x3da), X (0x3d4),
264: X (0x3cf), X (0x3c9), X (0x3c4), X (0x3bf), X (0x3b9), X (0x3b4), X (0x3ae), X (0x3a9),
265: X (0x3a4), X (0x39f), X (0x399), X (0x394), X (0x38f), X (0x38a), X (0x384), X (0x37f),
266: X (0x37a), X (0x375), X (0x370), X (0x36a), X (0x365), X (0x360), X (0x35b), X (0x356),
267: X (0x351), X (0x34c), X (0x347), X (0x342), X (0x33d), X (0x338), X (0x333), X (0x32e),
268: X (0x329), X (0x324), X (0x31f), X (0x31a), X (0x315), X (0x310), X (0x30b), X (0x306),
269: X (0x302), X (0x2fd), X (0x2f8), X (0x2f3), X (0x2ee), X (0x2e9), X (0x2e5), X (0x2e0),
270: X (0x2db), X (0x2d6), X (0x2d2), X (0x2cd), X (0x2c8), X (0x2c4), X (0x2bf), X (0x2ba),
271: X (0x2b5), X (0x2b1), X (0x2ac), X (0x2a8), X (0x2a3), X (0x29e), X (0x29a), X (0x295),
272: X (0x291), X (0x28c), X (0x288), X (0x283), X (0x27f), X (0x27a), X (0x276), X (0x271),
273: X (0x26d), X (0x268), X (0x264), X (0x25f), X (0x25b), X (0x257), X (0x252), X (0x24e),
274: X (0x249), X (0x245), X (0x241), X (0x23c), X (0x238), X (0x234), X (0x230), X (0x22b),
275: X (0x227), X (0x223), X (0x21e), X (0x21a), X (0x216), X (0x212), X (0x20e), X (0x209),
276: X (0x205), X (0x201), X (0x1fd), X (0x1f9), X (0x1f5), X (0x1f0), X (0x1ec), X (0x1e8),
277: X (0x1e4), X (0x1e0), X (0x1dc), X (0x1d8), X (0x1d4), X (0x1d0), X (0x1cc), X (0x1c8),
278: X (0x1c4), X (0x1c0), X (0x1bc), X (0x1b8), X (0x1b4), X (0x1b0), X (0x1ac), X (0x1a8),
279: X (0x1a4), X (0x1a0), X (0x19c), X (0x199), X (0x195), X (0x191), X (0x18d), X (0x189),
280: X (0x185), X (0x181), X (0x17e), X (0x17a), X (0x176), X (0x172), X (0x16f), X (0x16b),
281: X (0x167), X (0x163), X (0x160), X (0x15c), X (0x158), X (0x154), X (0x151), X (0x14d),
282: X (0x149), X (0x146), X (0x142), X (0x13e), X (0x13b), X (0x137), X (0x134), X (0x130),
283: X (0x12c), X (0x129), X (0x125), X (0x122), X (0x11e), X (0x11b), X (0x117), X (0x114),
284: X (0x110), X (0x10c), X (0x109), X (0x106), X (0x102), X (0x0ff), X (0x0fb), X (0x0f8),
285: X (0x0f4), X (0x0f1), X (0x0ed), X (0x0ea), X (0x0e7), X (0x0e3), X (0x0e0), X (0x0dc),
286: X (0x0d9), X (0x0d6), X (0x0d2), X (0x0cf), X (0x0cc), X (0x0c8), X (0x0c5), X (0x0c2),
287: X (0x0be), X (0x0bb), X (0x0b8), X (0x0b5), X (0x0b1), X (0x0ae), X (0x0ab), X (0x0a8),
288: X (0x0a4), X (0x0a1), X (0x09e), X (0x09b), X (0x098), X (0x094), X (0x091), X (0x08e),
289: X (0x08b), X (0x088), X (0x085), X (0x082), X (0x07e), X (0x07b), X (0x078), X (0x075),
290: X (0x072), X (0x06f), X (0x06c), X (0x069), X (0x066), X (0x063), X (0x060), X (0x05d),
291: X (0x05a), X (0x057), X (0x054), X (0x051), X (0x04e), X (0x04b), X (0x048), X (0x045),
292: X (0x042), X (0x03f), X (0x03c), X (0x039), X (0x036), X (0x033), X (0x030), X (0x02d),
293: X (0x02a), X (0x028), X (0x025), X (0x022), X (0x01f), X (0x01c), X (0x019), X (0x016),
294: X (0x014), X (0x011), X (0x00e), X (0x00b), X (0x008), X (0x006), X (0x003), X (0x000),
295: };
296:
297: public static final int[] s_increment_table = {
298: 0x00000000, 0x00000000, 0x10101010, 0x10101010,
299: 0x10101010, 0x10101010, 0x11101110, 0x11101110,
300: 0x10101010, 0x10111010, 0x11101110, 0x11111110,
301: 0x10101010, 0x10111010, 0x11101110, 0x11111110,
302: 0x10101010, 0x10111010, 0x11101110, 0x11111110,
303: 0x10101010, 0x10111010, 0x11101110, 0x11111110,
304: 0x10101010, 0x10111010, 0x11101110, 0x11111110,
305: 0x10101010, 0x10111010, 0x11101110, 0x11111110,
306: 0x10101010, 0x10111010, 0x11101110, 0x11111110,
307: 0x10101010, 0x10111010, 0x11101110, 0x11111110,
308: 0x10101010, 0x10111010, 0x11101110, 0x11111110,
309: 0x10101010, 0x10111010, 0x11101110, 0x11111110,
310: 0x11111111, 0x21112111, 0x21212121, 0x22212221,
311: 0x22222222, 0x42224222, 0x42424242, 0x44424442,
312: 0x44444444, 0x84448444, 0x84848484, 0x88848884,
313: 0x88888888, 0x88888888, 0x88888888, 0x88888888,
314: };
315:
316: public static final int[] s_detune_adjustment = {
317: 0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2,
318: 0, 1, 2, 2, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,
319: 0, 1, 2, 4, 0, 1, 3, 4, 0, 1, 3, 4, 0, 1, 3, 5,
320: 0, 2, 4, 5, 0, 2, 4, 6, 0, 2, 4, 6, 0, 2, 5, 7,
321: 0, 2, 5, 8, 0, 3, 6, 8, 0, 3, 6, 9, 0, 3, 7, 10,
322: 0, 4, 8, 11, 0, 4, 8, 12, 0, 4, 9, 13, 0, 5, 10, 14,
323: 0, 5, 11, 16, 0, 6, 12, 17, 0, 6, 13, 19, 0, 7, 14, 20,
324: 0, 8, 16, 22, 0, 8, 16, 22, 0, 8, 16, 22, 0, 8, 16, 22,
325: };
326:
327: public static final int[] s_phase_step = {
328: 41568, 41600, 41632, 41664, 41696, 41728, 41760, 41792, 41856, 41888, 41920, 41952, 42016, 42048, 42080, 42112,
329: 42176, 42208, 42240, 42272, 42304, 42336, 42368, 42400, 42464, 42496, 42528, 42560, 42624, 42656, 42688, 42720,
330: 42784, 42816, 42848, 42880, 42912, 42944, 42976, 43008, 43072, 43104, 43136, 43168, 43232, 43264, 43296, 43328,
331: 43392, 43424, 43456, 43488, 43552, 43584, 43616, 43648, 43712, 43744, 43776, 43808, 43872, 43904, 43936, 43968,
332: 44032, 44064, 44096, 44128, 44192, 44224, 44256, 44288, 44352, 44384, 44416, 44448, 44512, 44544, 44576, 44608,
333: 44672, 44704, 44736, 44768, 44832, 44864, 44896, 44928, 44992, 45024, 45056, 45088, 45152, 45184, 45216, 45248,
334: 45312, 45344, 45376, 45408, 45472, 45504, 45536, 45568, 45632, 45664, 45728, 45760, 45792, 45824, 45888, 45920,
335: 45984, 46016, 46048, 46080, 46144, 46176, 46208, 46240, 46304, 46336, 46368, 46400, 46464, 46496, 46528, 46560,
336: 46656, 46688, 46720, 46752, 46816, 46848, 46880, 46912, 46976, 47008, 47072, 47104, 47136, 47168, 47232, 47264,
337: 47328, 47360, 47392, 47424, 47488, 47520, 47552, 47584, 47648, 47680, 47744, 47776, 47808, 47840, 47904, 47936,
338: 48032, 48064, 48096, 48128, 48192, 48224, 48288, 48320, 48384, 48416, 48448, 48480, 48544, 48576, 48640, 48672,
339: 48736, 48768, 48800, 48832, 48896, 48928, 48992, 49024, 49088, 49120, 49152, 49184, 49248, 49280, 49344, 49376,
340: 49440, 49472, 49504, 49536, 49600, 49632, 49696, 49728, 49792, 49824, 49856, 49888, 49952, 49984, 50048, 50080,
341: 50144, 50176, 50208, 50240, 50304, 50336, 50400, 50432, 50496, 50528, 50560, 50592, 50656, 50688, 50752, 50784,
342: 50880, 50912, 50944, 50976, 51040, 51072, 51136, 51168, 51232, 51264, 51328, 51360, 51424, 51456, 51488, 51520,
343: 51616, 51648, 51680, 51712, 51776, 51808, 51872, 51904, 51968, 52000, 52064, 52096, 52160, 52192, 52224, 52256,
344: 52384, 52416, 52448, 52480, 52544, 52576, 52640, 52672, 52736, 52768, 52832, 52864, 52928, 52960, 52992, 53024,
345: 53120, 53152, 53216, 53248, 53312, 53344, 53408, 53440, 53504, 53536, 53600, 53632, 53696, 53728, 53792, 53824,
346: 53920, 53952, 54016, 54048, 54112, 54144, 54208, 54240, 54304, 54336, 54400, 54432, 54496, 54528, 54592, 54624,
347: 54688, 54720, 54784, 54816, 54880, 54912, 54976, 55008, 55072, 55104, 55168, 55200, 55264, 55296, 55360, 55392,
348: 55488, 55520, 55584, 55616, 55680, 55712, 55776, 55808, 55872, 55936, 55968, 56032, 56064, 56128, 56160, 56224,
349: 56288, 56320, 56384, 56416, 56480, 56512, 56576, 56608, 56672, 56736, 56768, 56832, 56864, 56928, 56960, 57024,
350: 57120, 57152, 57216, 57248, 57312, 57376, 57408, 57472, 57536, 57568, 57632, 57664, 57728, 57792, 57824, 57888,
351: 57952, 57984, 58048, 58080, 58144, 58208, 58240, 58304, 58368, 58400, 58464, 58496, 58560, 58624, 58656, 58720,
352: 58784, 58816, 58880, 58912, 58976, 59040, 59072, 59136, 59200, 59232, 59296, 59328, 59392, 59456, 59488, 59552,
353: 59648, 59680, 59744, 59776, 59840, 59904, 59936, 60000, 60064, 60128, 60160, 60224, 60288, 60320, 60384, 60416,
354: 60512, 60544, 60608, 60640, 60704, 60768, 60800, 60864, 60928, 60992, 61024, 61088, 61152, 61184, 61248, 61280,
355: 61376, 61408, 61472, 61536, 61600, 61632, 61696, 61760, 61824, 61856, 61920, 61984, 62048, 62080, 62144, 62208,
356: 62272, 62304, 62368, 62432, 62496, 62528, 62592, 62656, 62720, 62752, 62816, 62880, 62944, 62976, 63040, 63104,
357: 63200, 63232, 63296, 63360, 63424, 63456, 63520, 63584, 63648, 63680, 63744, 63808, 63872, 63904, 63968, 64032,
358: 64096, 64128, 64192, 64256, 64320, 64352, 64416, 64480, 64544, 64608, 64672, 64704, 64768, 64832, 64896, 64928,
359: 65024, 65056, 65120, 65184, 65248, 65312, 65376, 65408, 65504, 65536, 65600, 65664, 65728, 65792, 65856, 65888,
360: 65984, 66016, 66080, 66144, 66208, 66272, 66336, 66368, 66464, 66496, 66560, 66624, 66688, 66752, 66816, 66848,
361: 66944, 66976, 67040, 67104, 67168, 67232, 67296, 67328, 67424, 67456, 67520, 67584, 67648, 67712, 67776, 67808,
362: 67904, 67936, 68000, 68064, 68128, 68192, 68256, 68288, 68384, 68448, 68512, 68544, 68640, 68672, 68736, 68800,
363: 68896, 68928, 68992, 69056, 69120, 69184, 69248, 69280, 69376, 69440, 69504, 69536, 69632, 69664, 69728, 69792,
364: 69920, 69952, 70016, 70080, 70144, 70208, 70272, 70304, 70400, 70464, 70528, 70560, 70656, 70688, 70752, 70816,
365: 70912, 70976, 71040, 71104, 71136, 71232, 71264, 71360, 71424, 71488, 71552, 71616, 71648, 71744, 71776, 71872,
366: 71968, 72032, 72096, 72160, 72192, 72288, 72320, 72416, 72480, 72544, 72608, 72672, 72704, 72800, 72832, 72928,
367: 72992, 73056, 73120, 73184, 73216, 73312, 73344, 73440, 73504, 73568, 73632, 73696, 73728, 73824, 73856, 73952,
368: 74080, 74144, 74208, 74272, 74304, 74400, 74432, 74528, 74592, 74656, 74720, 74784, 74816, 74912, 74944, 75040,
369: 75136, 75200, 75264, 75328, 75360, 75456, 75488, 75584, 75648, 75712, 75776, 75840, 75872, 75968, 76000, 76096,
370: 76224, 76288, 76352, 76416, 76448, 76544, 76576, 76672, 76736, 76800, 76864, 76928, 77024, 77120, 77152, 77248,
371: 77344, 77408, 77472, 77536, 77568, 77664, 77696, 77792, 77856, 77920, 77984, 78048, 78144, 78240, 78272, 78368,
372: 78464, 78528, 78592, 78656, 78688, 78784, 78816, 78912, 78976, 79040, 79104, 79168, 79264, 79360, 79392, 79488,
373: 79616, 79680, 79744, 79808, 79840, 79936, 79968, 80064, 80128, 80192, 80256, 80320, 80416, 80512, 80544, 80640,
374: 80768, 80832, 80896, 80960, 80992, 81088, 81120, 81216, 81280, 81344, 81408, 81472, 81568, 81664, 81696, 81792,
375: 81952, 82016, 82080, 82144, 82176, 82272, 82304, 82400, 82464, 82528, 82592, 82656, 82752, 82848, 82880, 82976,
376: };
377:
378:
379:
380:
381: public static final int[] s_lfo_pm_shifts = {
382: 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
383: 0x77, 0x77, 0x77, 0x77, 0x72, 0x72, 0x72, 0x72,
384: 0x77, 0x77, 0x77, 0x72, 0x72, 0x72, 0x17, 0x17,
385: 0x77, 0x77, 0x72, 0x72, 0x17, 0x17, 0x12, 0x12,
386: 0x77, 0x77, 0x72, 0x17, 0x17, 0x17, 0x12, 0x07,
387: 0x77, 0x77, 0x17, 0x12, 0x07, 0x07, 0x02, 0x01,
388: 0x77, 0x77, 0x17, 0x12, 0x07, 0x07, 0x02, 0x01,
389: 0x77, 0x77, 0x17, 0x12, 0x07, 0x07, 0x02, 0x01,
390: };
391:
392:
393: public static final int LFO_WAVEFORM_LENGTH = 256;
394:
395:
396:
397:
398: private static int operator_list ( int o1, int o2, int o3, int o4) {
399: return o1 | (o2 << 8) | (o3 << 16) | (o4 << 24);
400: }
401:
402:
403:
404:
405:
406:
407:
408:
409:
410: public static final int[] s_fixed_map = {
411: operator_list ( 0, 16, 8, 24 ),
412: operator_list ( 1, 17, 9, 25 ),
413: operator_list ( 2, 18, 10, 26 ),
414: operator_list ( 3, 19, 11, 27 ),
415: operator_list ( 4, 20, 12, 28 ),
416: operator_list ( 5, 21, 13, 29 ),
417: operator_list ( 6, 22, 14, 30 ),
418: operator_list ( 7, 23, 15, 31 ),
419: };
420:
421:
422: private static int ALGORITHM (int op2in, int op3in, int op4in, int op1out, int op2out, int op3out) {
423: return op2in | (op3in << 1) | (op4in << 4) | (op1out << 7) | (op2out << 8) | (op3out << 9);
424: }
425: public static final int[] s_algorithm_ops = {
426: ALGORITHM (1,2,3, 0,0,0),
427: ALGORITHM (0,5,3, 0,0,0),
428: ALGORITHM (0,2,6, 0,0,0),
429: ALGORITHM (1,0,7, 0,0,0),
430: ALGORITHM (1,0,3, 0,1,0),
431: ALGORITHM (1,1,1, 0,1,1),
432: ALGORITHM (1,0,0, 0,1,1),
433: ALGORITHM (0,0,0, 1,1,1),
434: ALGORITHM (1,2,3, 0,0,0),
435: ALGORITHM (0,2,3, 1,0,0),
436: ALGORITHM (1,0,3, 0,1,0),
437: ALGORITHM (0,2,0, 1,0,1),
438: };
439:
440: public static final int[] s_detune2_delta = { 0, (600*64+50)/100, (781*64+50)/100, (950*64+50)/100 };
441:
442:
443:
444: public static final int KEYON_NORMAL = 0;
445: public static final int KEYON_RHYTHM = 1;
446: public static final int KEYON_CSM = 2;
447:
448:
449:
450:
451:
452:
453:
454:
455:
456:
457: public static int abs_sin_attenuation ( int input) {
458:
459:
460: if (bitfield (input, 8) != 0) {
461: input = ~input;
462: }
463:
464: return s_sin_table[input & 0xff];
465: }
466:
467:
468:
469:
470:
471:
472: public static int attenuation_to_volume ( int input) {
473:
474:
475:
476:
477:
478:
479:
480:
481: return s_power_table[input & 0xff] >>> (input >>> 8);
482: }
483:
484:
485:
486:
487:
488:
489:
490:
491: public static int attenuation_increment ( int rate, int index) {
492: return bitfield (s_increment_table[rate], 4 * index, 4);
493: }
494:
495:
496:
497:
498:
499:
500:
501:
502:
503: public static int detune_adjustment ( int detune, int keycode) {
504: int result = s_detune_adjustment[4 * keycode + (detune & 3)];
505: return bitfield (detune, 2) != 0 ? -result : result;
506: }
507:
508:
509:
510:
511:
512:
513:
514:
515:
516: public static int opm_key_code_to_phase_step ( int block_freq, int delta) {
517:
518:
519:
520:
521:
522:
523:
524:
525:
526:
527:
528:
529:
530:
531:
532:
533:
534:
535:
536:
537:
538:
539:
540:
541: int block = bitfield (block_freq, 10, 3);
542:
543:
544:
545:
546:
547: int adjusted_code = bitfield (block_freq, 6, 4) - bitfield (block_freq, 8, 2);
548:
549:
550: int eff_freq = (adjusted_code << 6) | bitfield (block_freq, 0, 6);
551:
552:
553: eff_freq += delta;
554:
555:
556: if (Integer.compareUnsigned (eff_freq, 768) >= 0) {
557:
558: if (eff_freq < 0) {
559: eff_freq += 768;
560: if (block-- == 0) {
561: return s_phase_step[0] >>> 7;
562: }
563: }
564:
565:
566: else {
567: eff_freq -= 768;
568: if (eff_freq >= 768) {
569: block++;
570: eff_freq -= 768;
571: }
572: if (block++ >= 7) {
573: return s_phase_step[767];
574: }
575: }
576: }
577:
578:
579: return s_phase_step[eff_freq] >>> (block ^ 7);
580: }
581:
582:
583:
584:
585:
586:
587:
588:
589: public static int opn_lfo_pm_phase_adjustment ( int fnum_bits, int pm_sensitivity, int lfo_raw_pm) {
590:
591: int abs_pm = (lfo_raw_pm < 0) ? -lfo_raw_pm : lfo_raw_pm;
592: int shifts = s_lfo_pm_shifts[8 * pm_sensitivity + bitfield (abs_pm, 0, 3)];
593:
594:
595: int adjust = (fnum_bits >>> bitfield (shifts, 0, 4)) + (fnum_bits >>> bitfield (shifts, 4, 4));
596: if (pm_sensitivity > 5) {
597: adjust <<= pm_sensitivity - 5;
598: }
599: adjust >>= 2;
600:
601:
602: return (lfo_raw_pm < 0) ? -adjust : adjust;
603: }
604:
605:
606:
607:
608:
609:
610: class opdata_cache {
611: int[] waveform;
612: int phase_step;
613: int total_level;
614: int block_freq;
615: int detune;
616: int multiple;
617: int eg_sustain;
618: int[] eg_rate;
619: int eg_shift;
620: public opdata_cache () {
621: eg_rate = new int[EG_STATES];
622: eg_shift = 0;
623: }
624: }
625:
626:
627:
628:
629:
630:
631:
632: protected static int effective_rate ( int rawrate, int ksr) {
633: return (rawrate == 0) ? 0 : umin32 (rawrate + ksr, 63);
634: }
635:
636:
637:
638:
639:
640: class fm_operator {
641:
642:
643: private int m_choffs;
644: private int m_opoffs;
645: private int m_phase;
646: public int m_env_attenuation;
647: public int m_env_state;
648: private int m_key_state;
649: private int m_keyon_live;
650: private opdata_cache m_cache;
651:
652:
653:
654:
655:
656: public fm_operator ( int opoffs) {
657: m_choffs = 0;
658: m_opoffs = opoffs;
659: m_phase = 0;
660: m_env_attenuation = uint16 (0x3ff);
661: m_env_state = EG_RELEASE;
662: m_key_state = uint8 (0);
663: m_keyon_live = uint8 (0);
664: m_cache = new opdata_cache ();
665: }
666:
667:
668:
669:
670:
671: public void reset () {
672:
673: m_phase = 0;
674: m_env_attenuation = uint16 (0x3ff);
675: m_env_state = EG_RELEASE;
676: m_key_state = uint8 (0);
677: m_keyon_live = uint8 (0);
678: }
679:
680:
681: public void set_choffs ( int choffs) {
682: m_choffs = choffs;
683: }
684:
685:
686:
687:
688:
689: public boolean prepare () {
690:
691: cache_operator_data (m_choffs, m_opoffs, m_cache);
692:
693:
694: clock_keystate (m_keyon_live != 0 ? 1 : 0);
695:
696: m_keyon_live = uint8 (m_keyon_live & (~(1 << KEYON_CSM)));
697:
698:
699: return (m_env_state != EG_RELEASE || Integer.compareUnsigned (m_env_attenuation, EG_QUIET) < 0);
700: }
701:
702:
703:
704:
705:
706: public void clock ( int env_counter, int lfo_raw_pm) {
707:
708: if (bitfield (env_counter, 0, 2) == 0) {
709: clock_envelope (env_counter >>> 2);
710: }
711:
712:
713:
714:
715:
716:
717:
718:
719:
720: int phase_step = m_cache.phase_step;
721: if (phase_step == PHASE_STEP_DYNAMIC) {
722: phase_step = compute_phase_step (m_choffs, m_opoffs, m_cache, lfo_raw_pm);
723: }
724:
725:
726: m_phase += phase_step;
727: }
728:
729:
730:
731: public int phase () {
732: return m_phase >>> 10;
733: }
734:
735:
736:
737:
738:
739:
740:
741:
742: public int compute_volume ( int phase, int am_offset) {
743:
744:
745:
746:
747: if (Integer.compareUnsigned (m_env_attenuation, EG_QUIET) > 0) {
748: return 0;
749: }
750:
751:
752: int sin_attenuation = m_cache.waveform[phase & (WAVEFORM_LENGTH - 1)];
753:
754:
755: int env_attenuation = envelope_attenuation (am_offset) << 2;
756:
757:
758: int result = attenuation_to_volume ((sin_attenuation & 0x7fff) + env_attenuation);
759:
760:
761: return bitfield (sin_attenuation, 15) != 0 ? -result : result;
762: }
763:
764:
765:
766:
767:
768:
769:
770:
771: public int compute_noise_volume ( int am_offset) {
772:
773:
774:
775: int result = (envelope_attenuation (am_offset) ^ 0x3ff) << 1;
776:
777:
778:
779:
780: return bitfield (noise_state (), 0) != 0 ? -result : result;
781: }
782:
783:
784:
785:
786:
787:
788: public void keyonoff ( int on, int type) {
789: m_keyon_live = uint8 ((m_keyon_live & ~(1 << type)) | (bitfield (on, 0) << type));
790: }
791:
792:
793:
794:
795:
796:
797:
798:
799: private void start_attack () {
800: start_attack (false);
801: }
802: private void start_attack (boolean is_restart) {
803:
804: if (m_env_state == EG_ATTACK) {
805: return;
806: }
807: m_env_state = EG_ATTACK;
808:
809:
810:
811:
812:
813:
814:
815:
816: if (!is_restart) {
817: m_phase = 0;
818: }
819:
820:
821: if (Integer.compareUnsigned (m_cache.eg_rate[EG_ATTACK], 62) >= 0) {
822: m_env_attenuation = uint16 (0);
823: }
824: }
825:
826:
827:
828:
829:
830:
831:
832: private void start_release () {
833:
834: if (m_env_state >= EG_RELEASE) {
835: return;
836: }
837: m_env_state = EG_RELEASE;
838:
839:
840:
841: }
842:
843:
844:
845:
846:
847:
848:
849: private void clock_keystate ( int keystate) {
850:
851:
852: if ((keystate ^ m_key_state) != 0) {
853: m_key_state = uint8 (keystate);
854:
855:
856: if (keystate != 0) {
857:
858:
859: start_attack ();
860: }
861:
862:
863: else {
864: start_release ();
865: }
866: }
867: }
868:
869:
870:
871:
872:
873:
874:
875:
876:
877:
878:
879:
880: private void clock_envelope ( int env_counter) {
881:
882: if (m_env_state == EG_ATTACK && m_env_attenuation == 0) {
883: m_env_state = EG_DECAY;
884: }
885:
886:
887:
888:
889:
890:
891: if (m_env_state == EG_DECAY && Integer.compareUnsigned (m_env_attenuation, m_cache.eg_sustain) >= 0) {
892: m_env_state = EG_SUSTAIN;
893: }
894:
895:
896: int rate = m_cache.eg_rate[m_env_state];
897:
898:
899:
900:
901: int rate_shift = rate >>> 2;
902: env_counter <<= rate_shift;
903:
904:
905: if (bitfield (env_counter, 0, 11) != 0) {
906: return;
907: }
908:
909:
910: int relevant_bits = bitfield (env_counter, (rate_shift <= 11) ? 11 : rate_shift, 3);
911: int increment = attenuation_increment (rate, relevant_bits);
912:
913:
914: if (m_env_state == EG_ATTACK) {
915:
916:
917:
918:
919: if (rate < 62) {
920:
921: m_env_attenuation = uint16 (m_env_attenuation + ((~m_env_attenuation * increment) >>> 4));
922: }
923: }
924:
925:
926: else {
927:
928:
929: m_env_attenuation = uint16 (m_env_attenuation + increment);
930:
931:
932:
933:
934: if (Integer.compareUnsigned (m_env_attenuation, 0x400) >= 0) {
935: m_env_attenuation = uint16 (0x3ff);
936: }
937:
938:
939:
940:
941:
942: }
943: }
944:
945:
946:
947:
948:
949:
950:
951:
952:
953: private int envelope_attenuation ( int am_offset) {
954: int result = m_env_attenuation >>> m_cache.eg_shift;
955:
956:
957:
958:
959: if (op_lfo_am_enable (m_opoffs) != 0) {
960: result += am_offset;
961: }
962:
963:
964: result += m_cache.total_level;
965:
966:
967: return umin32 (result, 0x3ff);
968: }
969:
970: }
971:
972:
973:
974:
975:
976: class fm_channel {
977:
978:
979: private int m_choffs;
980: private int m_feedback_0, m_feedback_1;
981: private int m_feedback_in;
982: public fm_operator[] m_op;
983:
984:
985:
986:
987:
988:
989: public fm_channel ( int choffs) {
990: m_choffs = choffs;
991: m_feedback_0 = m_feedback_1 = sint16 (0);
992: m_feedback_in = sint16 (0);
993: m_op = new fm_operator[4];
994: }
995:
996:
997:
998:
999:
1000:
1001: public void reset () {
1002:
1003: m_feedback_0 = m_feedback_1 = sint16 (0);
1004: m_feedback_in = sint16 (0);
1005: }
1006:
1007:
1008:
1009:
1010: public void assign ( int index, fm_operator op) {
1011: m_op[index] = op;
1012: op.set_choffs (m_choffs);
1013: }
1014:
1015:
1016:
1017:
1018:
1019:
1020: public void keyonoff ( int states, int type, int chnum) {
1021: for ( int opnum = 0; opnum < 4; opnum++) {
1022: m_op[opnum].keyonoff (bitfield (states, opnum), type);
1023: }
1024: }
1025:
1026:
1027:
1028:
1029:
1030:
1031: public boolean prepare () {
1032: int active_mask = 0;
1033:
1034:
1035: for ( int opnum = 0; opnum < 4; opnum++) {
1036: if (m_op[opnum].prepare ()) {
1037: active_mask |= 1 << opnum;
1038: }
1039: }
1040:
1041: return (active_mask != 0);
1042: }
1043:
1044:
1045:
1046:
1047:
1048:
1049: public void clock ( int env_counter, int lfo_raw_pm) {
1050:
1051: m_feedback_0 = sint16 (m_feedback_1);
1052: m_feedback_1 = sint16 (m_feedback_in);
1053:
1054: for ( int opnum = 0; opnum < 4; opnum++) {
1055: m_op[opnum].clock (env_counter, lfo_raw_pm);
1056: }
1057: }
1058:
1059:
1060:
1061:
1062:
1063:
1064:
1065:
1066:
1067:
1068:
1069:
1070:
1071:
1072:
1073:
1074: public void output_4op ( int rshift, int clipmax) {
1075:
1076:
1077:
1078: int am_offset = lfo_am_offset (m_choffs);
1079:
1080:
1081: int opmod = 0;
1082: int feedback = ch_feedback (m_choffs);
1083: if (feedback != 0) {
1084: opmod = (m_feedback_0 + m_feedback_1) >> (10 - feedback);
1085: }
1086:
1087:
1088: int op1value = m_feedback_in = sint16 (m_op[0].compute_volume (m_op[0].phase () + opmod, am_offset));
1089:
1090:
1091:
1092: if (ch_output_any (m_choffs) == 0) {
1093: return;
1094: }
1095:
1096:
1097:
1098:
1099:
1100:
1101:
1102:
1103:
1104:
1105:
1106:
1107:
1108:
1109:
1110:
1111:
1112:
1113:
1114:
1115:
1116:
1117:
1118:
1119: int algorithm_ops = s_algorithm_ops[ch_algorithm (m_choffs)];
1120:
1121:
1122: int[] opout = new int[8];
1123: opout[0] = sint16 (0);
1124: opout[1] = sint16 (op1value);
1125:
1126:
1127: opmod = opout[bitfield (algorithm_ops, 0, 1)] >> 1;
1128: opout[2] = sint16 (m_op[1].compute_volume (m_op[1].phase () + opmod, am_offset));
1129: opout[5] = sint16 (opout[1] + opout[2]);
1130:
1131:
1132: opmod = opout[bitfield (algorithm_ops, 1, 3)] >> 1;
1133: opout[3] = sint16 (m_op[2].compute_volume (m_op[2].phase () + opmod, am_offset));
1134: opout[6] = sint16 (opout[1] + opout[3]);
1135: opout[7] = sint16 (opout[2] + opout[3]);
1136:
1137:
1138:
1139: int result;
1140: if (noise_enable () != 0 && m_choffs == 7) {
1141: result = m_op[3].compute_noise_volume (am_offset);
1142: } else {
1143: opmod = opout[bitfield (algorithm_ops, 4, 3)] >> 1;
1144: result = m_op[3].compute_volume (m_op[3].phase () + opmod, am_offset);
1145: }
1146: result >>= rshift;
1147:
1148:
1149: int clipmin = -clipmax - 1;
1150: if (bitfield (algorithm_ops, 7) != 0) {
1151: result = clamp (result + (opout[1] >> rshift), clipmin, clipmax);
1152: }
1153: if (bitfield (algorithm_ops, 8) != 0) {
1154: result = clamp (result + (opout[2] >> rshift), clipmin, clipmax);
1155: }
1156: if (bitfield (algorithm_ops, 9) != 0) {
1157: result = clamp (result + (opout[3] >> rshift), clipmin, clipmax);
1158: }
1159:
1160:
1161: if (ch_output_0 (m_choffs) != 0) {
1162: buffer[pointer ] += result;
1163: }
1164: if (ch_output_1 (m_choffs) != 0) {
1165: buffer[pointer + 1] += result;
1166: }
1167: }
1168:
1169: }
1170:
1171:
1172:
1173:
1174:
1175: private int m_address;
1176:
1177:
1178:
1179:
1180:
1181:
1182:
1183:
1184:
1185: private int m_env_counter;
1186: private int m_status;
1187: private int m_clock_prescale;
1188: private int m_irq_mask;
1189: private boolean m_irq_state;
1190: private boolean[] m_timer_running;
1191: private int m_total_clocks;
1192: private int m_active_channels;
1193: private int m_modified_channels;
1194: private int m_prepare_count;
1195: public fm_channel[] m_channel = new fm_channel[CHANNELS];
1196: private fm_operator[] m_operator = new fm_operator[OPERATORS];
1197:
1198:
1199:
1200:
1201:
1202:
1203:
1204:
1205:
1206:
1207:
1208:
1209:
1210:
1211:
1212:
1213:
1214:
1215:
1216:
1217:
1218:
1219:
1220:
1221:
1222:
1223:
1224:
1225:
1226:
1227:
1228:
1229:
1230:
1231:
1232:
1233:
1234:
1235:
1236:
1237:
1238:
1239:
1240:
1241:
1242:
1243:
1244:
1245:
1246:
1247:
1248:
1249:
1250:
1251:
1252:
1253: protected int m_lfo_counter;
1254: protected int m_noise_lfsr;
1255: protected int m_noise_counter;
1256: protected int m_noise_state;
1257: protected int m_noise_lfo;
1258: protected int m_lfo_am;
1259: protected int[] m_regdata;
1260: protected int[] m_lfo_waveform;
1261: protected int[] m_waveform;
1262:
1263:
1264:
1265: public YM2151 () {
1266:
1267:
1268:
1269:
1270: m_address = uint8 (0);
1271:
1272:
1273:
1274:
1275:
1276: m_env_counter = 0;
1277: m_status = uint8 (0);
1278: m_clock_prescale = uint8 (DEFAULT_PRESCALE);
1279: m_irq_mask = uint8 (STATUS_TIMERA | STATUS_TIMERB);
1280: m_irq_state = false;
1281: m_timer_running = new boolean[] { false, false };
1282: m_active_channels = ALL_CHANNELS;
1283: m_modified_channels = ALL_CHANNELS;
1284: m_prepare_count = 0;
1285:
1286:
1287:
1288:
1289:
1290: for ( int chnum = 0; chnum < CHANNELS; chnum++) {
1291: m_channel[chnum] = new fm_channel (channel_offset (chnum));
1292: }
1293:
1294:
1295: for ( int opnum = 0; opnum < OPERATORS; opnum++) {
1296: m_operator[opnum] = new fm_operator (operator_offset (opnum));
1297: }
1298:
1299:
1300:
1301:
1302:
1303:
1304:
1305: for ( int chnum = 0; chnum < CHANNELS; chnum++) {
1306: for ( int index = 0; index < 4; index++) {
1307: int opnum = bitfield (s_fixed_map[chnum], 8 * index, 8);
1308: m_channel[chnum].assign (index, m_operator[opnum]);
1309: }
1310: }
1311:
1312:
1313:
1314:
1315: m_lfo_counter = 0;
1316: m_noise_lfsr = 1;
1317: m_noise_counter = uint8 (0);
1318: m_noise_state = uint8 (0);
1319: m_noise_lfo = uint8 (0);
1320: m_lfo_am = uint8 (0);
1321:
1322: m_regdata = new int[REGISTERS];
1323: m_lfo_waveform = new int[LFO_WAVEFORM_LENGTH * 4];
1324: m_waveform = new int[WAVEFORM_LENGTH * WAVEFORMS];
1325:
1326:
1327: for ( int index = 0; index < WAVEFORM_LENGTH; index++) {
1328: m_waveform[WAVEFORM_LENGTH * 0 + index] = uint16 (abs_sin_attenuation (index) | (bitfield (index, 9) << 15));
1329: }
1330:
1331:
1332:
1333: for ( int index = 0; index < LFO_WAVEFORM_LENGTH; index++) {
1334:
1335: int am = uint8 (index ^ 0xff);
1336: int pm = sint8 (index);
1337: m_lfo_waveform[LFO_WAVEFORM_LENGTH * 0 + index] = sint16 (am | (pm << 8));
1338:
1339:
1340: am = uint8 (bitfield (index, 7) != 0 ? 0 : 0xff);
1341: pm = sint8 (am ^ 0x80);
1342: m_lfo_waveform[LFO_WAVEFORM_LENGTH * 1 + index] = sint16 (am | (pm << 8));
1343:
1344:
1345: am = uint8 (bitfield (index, 7) != 0 ? (index << 1) : ((index ^ 0xff) << 1));
1346: pm = sint8 (bitfield (index, 6) != 0 ? am : ~am);
1347: m_lfo_waveform[LFO_WAVEFORM_LENGTH * 2 + index] = sint16 (am | (pm << 8));
1348:
1349:
1350: m_lfo_waveform[LFO_WAVEFORM_LENGTH * 3 + index] = sint16 (0);
1351: }
1352:
1353: init2 ();
1354: }
1355:
1356:
1357:
1358:
1359:
1360:
1361:
1362:
1363:
1364: public void reset () {
1365:
1366:
1367: set_reset_status (0, 0xff);
1368:
1369:
1370:
1371:
1372:
1373:
1374: Arrays.fill (m_regdata, 0, REGISTERS, uint8 (0));
1375:
1376:
1377: m_regdata[0x20] = m_regdata[0x21] = m_regdata[0x22] = m_regdata[0x23] = uint8 (0xc0);
1378: m_regdata[0x24] = m_regdata[0x25] = m_regdata[0x26] = m_regdata[0x27] = uint8 (0xc0);
1379:
1380:
1381:
1382: writeAddress (REG_MODE);
1383: writeData (0);
1384:
1385:
1386: for (fm_channel chan : m_channel) {
1387: chan.reset ();
1388: }
1389:
1390:
1391: for (fm_operator op : m_operator) {
1392: op.reset ();
1393: }
1394: }
1395:
1396:
1397:
1398:
1399:
1400: public int readStatus () {
1401: int result = uint8 (status ());
1402:
1403: if (listener != null && listener.isBusy ()) {
1404:
1405: result = uint8 (result | STATUS_BUSY);
1406: }
1407: return uint8 (result);
1408: }
1409:
1410:
1411:
1412:
1413:
1414: public void writeAddress (int address) {
1415: address &= 0xff;
1416:
1417:
1418: m_address = address;
1419: }
1420:
1421:
1422:
1423:
1424:
1425: public void writeData (int data) {
1426: data &= 0xff;
1427: if (listener != null) {
1428: listener.written (pointer, m_address, data);
1429: }
1430:
1431:
1432:
1433:
1434: if (m_address == REG_MODE) {
1435:
1436: engine_mode_write (data);
1437: return;
1438: }
1439:
1440:
1441: m_modified_channels = ALL_CHANNELS;
1442:
1443:
1444: regs_write (m_address, data);
1445:
1446: if (m_address == 0x08) {
1447: int keyon_channel = bitfield (data, 0, 3);
1448: int keyon_opmask = bitfield (data, 3, 4);
1449:
1450: if (keyon_channel < CHANNELS) {
1451:
1452: m_channel[keyon_channel].keyonoff (keyon_opmask, KEYON_NORMAL, keyon_channel);
1453: }
1454: }
1455:
1456:
1457: if (m_address == 0x1b) {
1458:
1459:
1460: if (listener != null) {
1461: listener.control ((data >>> 6) & 3);
1462: }
1463: }
1464:
1465:
1466:
1467: listener.busy (32 * clock_prescale ());
1468: }
1469:
1470:
1471:
1472:
1473:
1474:
1475: public void generate (int limit) {
1476: for (; pointer < limit; pointer += 2) {
1477:
1478:
1479:
1480:
1481:
1482:
1483:
1484:
1485:
1486:
1487:
1488: m_total_clocks = uint8 (m_total_clocks + 1);
1489:
1490:
1491:
1492: if (m_modified_channels != 0 || Integer.compareUnsigned (m_prepare_count++, 4096) >= 0) {
1493:
1494:
1495: m_active_channels = 0;
1496: for ( int chnum = 0; chnum < CHANNELS; chnum++) {
1497: if (m_channel[chnum].prepare ()) {
1498: m_active_channels |= 1 << chnum;
1499: }
1500: }
1501:
1502:
1503: m_modified_channels = m_prepare_count = 0;
1504: }
1505:
1506:
1507:
1508: if (EG_CLOCK_DIVIDER == 1) {
1509: m_env_counter += 4;
1510: } else if (bitfield (++m_env_counter, 0, 2) == EG_CLOCK_DIVIDER) {
1511: m_env_counter += 4 - EG_CLOCK_DIVIDER;
1512: }
1513:
1514:
1515: int lfo_raw_pm = clock_noise_and_lfo ();
1516:
1517:
1518: for ( int chnum = 0; chnum < CHANNELS; chnum++) {
1519: m_channel[chnum].clock (m_env_counter, lfo_raw_pm);
1520: }
1521:
1522:
1523:
1524:
1525: buffer[pointer ] = 0;
1526: buffer[pointer + 1] = 0;
1527: int chanmask = channelMask;
1528:
1529:
1530:
1531:
1532: chanmask &= m_active_channels;
1533:
1534:
1535: for ( int chnum = 0; chnum < CHANNELS; chnum++) {
1536: if (bitfield (chanmask, chnum) != 0) {
1537: m_channel[chnum].output_4op (0, 32767);
1538: }
1539: }
1540:
1541:
1542:
1543:
1544:
1545: buffer[pointer ] = roundtrip_fp (buffer[pointer ]);
1546: buffer[pointer + 1] = roundtrip_fp (buffer[pointer + 1]);
1547:
1548: }
1549: }
1550:
1551:
1552:
1553:
1554:
1555:
1556:
1557:
1558:
1559:
1560: public int status () {
1561: return uint8 (m_status & ~STATUS_BUSY);
1562: }
1563:
1564:
1565: public int set_reset_status ( int set, int reset) {
1566: m_status = uint8 ((m_status | set) & ~(reset | STATUS_BUSY));
1567:
1568: engine_check_interrupts ();
1569: return uint8 (m_status);
1570: }
1571:
1572:
1573: public void set_irq_mask ( int mask) {
1574: m_irq_mask = uint8 (mask);
1575:
1576: engine_check_interrupts ();
1577: }
1578:
1579:
1580: public int clock_prescale () {
1581: return m_clock_prescale;
1582: }
1583:
1584:
1585: public void set_clock_prescale ( int prescale) {
1586: m_clock_prescale = uint8 (prescale);
1587: }
1588:
1589:
1590:
1591:
1592:
1593:
1594: public void engine_timer_expired ( int tnum) {
1595:
1596: if (tnum == 0 && enable_timer_a () != 0) {
1597: set_reset_status (STATUS_TIMERA, 0);
1598: } else if (tnum == 1 && enable_timer_b () != 0) {
1599: set_reset_status (STATUS_TIMERB, 0);
1600: }
1601:
1602:
1603: if (tnum == 0 && csm () != 0) {
1604: for ( int chnum = 0; chnum < CHANNELS; chnum++) {
1605: if (bitfield (CSM_TRIGGER_MASK, chnum) != 0) {
1606: m_channel[chnum].keyonoff (1, KEYON_CSM, chnum);
1607: m_modified_channels |= 1 << chnum;
1608: }
1609: }
1610: }
1611:
1612:
1613: m_timer_running[tnum] = false;
1614: update_timer (tnum, 1, 0);
1615: }
1616:
1617:
1618:
1619:
1620:
1621:
1622: public void engine_check_interrupts () {
1623:
1624: boolean old_state = m_irq_state;
1625: m_irq_state = (m_status & m_irq_mask) != 0;
1626:
1627:
1628: if (m_irq_state) {
1629:
1630: m_status = uint8 (m_status | STATUS_IRQ);
1631: } else {
1632:
1633: m_status = uint8 (m_status & (~STATUS_IRQ));
1634: }
1635:
1636:
1637: if (old_state != m_irq_state) {
1638:
1639: listener.irq (m_irq_state);
1640: }
1641: }
1642:
1643:
1644:
1645:
1646:
1647:
1648: public void engine_mode_write ( int data) {
1649:
1650: m_modified_channels = ALL_CHANNELS;
1651:
1652:
1653: regs_write (REG_MODE, data);
1654:
1655:
1656:
1657:
1658:
1659:
1660: int reset_mask = 0;
1661: if (reset_timer_b () != 0) {
1662:
1663: reset_mask = uint8 (reset_mask | STATUS_TIMERB);
1664: }
1665: if (reset_timer_a () != 0) {
1666:
1667: reset_mask = uint8 (reset_mask | STATUS_TIMERA);
1668: }
1669: set_reset_status (0, reset_mask);
1670:
1671:
1672:
1673:
1674: updateTimerB (load_timer_b (), -(m_total_clocks & 15));
1675: updateTimerA (load_timer_a (), 0);
1676: }
1677:
1678: protected void updateTimerA (int enable, int delta_clocks) {
1679: update_timer (0, enable, delta_clocks);
1680: }
1681: protected void updateTimerB (int enable, int delta_clocks) {
1682: update_timer (1, enable, delta_clocks);
1683: }
1684:
1685:
1686:
1687:
1688:
1689:
1690: protected void update_timer ( int tnum, int enable, int delta_clocks) {
1691:
1692: if (enable != 0 && !m_timer_running[tnum]) {
1693:
1694: int period = (tnum == 0) ? (1024 - timer_a_value ()) : 16 * (256 - timer_b_value ());
1695:
1696:
1697: period += delta_clocks;
1698:
1699:
1700:
1701: if (tnum == 0) {
1702: listener.timerA (period * OPERATORS * m_clock_prescale);
1703: } else {
1704: listener.timerB (period * OPERATORS * m_clock_prescale);
1705: }
1706: m_timer_running[tnum] = true;
1707: }
1708:
1709:
1710: else if (enable == 0) {
1711:
1712: if (tnum == 0) {
1713: listener.timerA (-1);
1714: } else {
1715: listener.timerB (-1);
1716: }
1717: m_timer_running[tnum] = false;
1718: }
1719: }
1720:
1721:
1722:
1723:
1724:
1725:
1726: public static int channel_offset ( int chnum) {
1727: return chnum;
1728: }
1729:
1730:
1731: public static int operator_offset ( int opnum) {
1732: return opnum;
1733: }
1734:
1735:
1736:
1737:
1738:
1739: public void regs_write ( int index, int data) {
1740:
1741:
1742: if (index == 0x19) {
1743: m_regdata[index + bitfield (data, 7)] = uint8 (data);
1744: } else if (index != 0x1a) {
1745: m_regdata[index] = uint8 (data);
1746: }
1747: }
1748:
1749:
1750:
1751:
1752:
1753:
1754:
1755: public int clock_noise_and_lfo () {
1756:
1757:
1758: int freq = noise_frequency ();
1759: for (int rep = 0; rep < 2; rep++) {
1760:
1761:
1762:
1763:
1764: m_noise_lfsr <<= 1;
1765: m_noise_lfsr |= bitfield (m_noise_lfsr, 17) ^ bitfield (m_noise_lfsr, 14) ^ 1;
1766:
1767:
1768:
1769: if (Integer.compareUnsigned ((m_noise_counter = uint8 (m_noise_counter + 1)), freq) >= 0) {
1770: m_noise_counter = uint8 (0);
1771: m_noise_state = uint8 (bitfield (m_noise_lfsr, 17));
1772: }
1773: }
1774:
1775:
1776:
1777:
1778: int rate = lfo_rate ();
1779: m_lfo_counter += (0x10 | bitfield (rate, 0, 4)) << bitfield (rate, 4, 4);
1780:
1781:
1782:
1783: if (lfo_reset () != 0) {
1784: m_lfo_counter = 0;
1785: }
1786:
1787:
1788: int lfo = bitfield (m_lfo_counter, 22, 8);
1789:
1790:
1791:
1792:
1793: int lfo_noise = bitfield (m_noise_lfsr, 17, 8);
1794: m_lfo_waveform[LFO_WAVEFORM_LENGTH * 3 + ((lfo + 1) & 0xff)] = sint16 (lfo_noise | (lfo_noise << 8));
1795:
1796:
1797:
1798:
1799: int ampm = m_lfo_waveform[LFO_WAVEFORM_LENGTH * lfo_waveform () + lfo];
1800:
1801:
1802: m_lfo_am = uint8 (((ampm & 0xff) * lfo_am_depth ()) >>> 7);
1803:
1804:
1805: return ((ampm >> 8) * lfo_pm_depth ()) >> 7;
1806: }
1807:
1808:
1809:
1810:
1811:
1812:
1813: public int lfo_am_offset ( int choffs) {
1814:
1815:
1816:
1817:
1818: int am_sensitivity = ch_lfo_am_sens (choffs);
1819: if (am_sensitivity == 0) {
1820: return 0;
1821: }
1822:
1823:
1824:
1825:
1826:
1827:
1828:
1829: return m_lfo_am << (am_sensitivity - 1);
1830: }
1831:
1832:
1833: public int noise_state () {
1834: return m_noise_state;
1835: }
1836:
1837:
1838:
1839:
1840:
1841:
1842: public void cache_operator_data ( int choffs, int opoffs, opdata_cache cache) {
1843:
1844: cache.waveform = m_waveform;
1845:
1846:
1847: int block_freq = cache.block_freq = ch_block_freq (choffs);
1848:
1849:
1850:
1851:
1852:
1853:
1854:
1855:
1856: int keycode = bitfield (block_freq, 8, 5);
1857:
1858:
1859: cache.detune = detune_adjustment (op_detune (opoffs), keycode);
1860:
1861:
1862: cache.multiple = op_multiple (opoffs) * 2;
1863: if (cache.multiple == 0) {
1864: cache.multiple = 1;
1865: }
1866:
1867:
1868:
1869: if (lfo_pm_depth () == 0 || ch_lfo_pm_sens (choffs) == 0){
1870: cache.phase_step = compute_phase_step (choffs, opoffs, cache, 0);
1871: } else {
1872: cache.phase_step = PHASE_STEP_DYNAMIC;
1873: }
1874:
1875:
1876: cache.total_level = op_total_level (opoffs) << 3;
1877:
1878:
1879: cache.eg_sustain = op_sustain_level (opoffs);
1880: cache.eg_sustain |= (cache.eg_sustain + 1) & 0x10;
1881: cache.eg_sustain <<= 5;
1882:
1883:
1884: int ksrval = keycode >>> (op_ksr (opoffs) ^ 3);
1885: cache.eg_rate[EG_ATTACK] = uint8 (effective_rate (op_attack_rate (opoffs) * 2, ksrval));
1886: cache.eg_rate[EG_DECAY] = uint8 (effective_rate (op_decay_rate (opoffs) * 2, ksrval));
1887: cache.eg_rate[EG_SUSTAIN] = uint8 (effective_rate (op_sustain_rate (opoffs) * 2, ksrval));
1888: cache.eg_rate[EG_RELEASE] = uint8 (effective_rate (op_release_rate (opoffs) * 4 + 2, ksrval));
1889: }
1890:
1891:
1892:
1893:
1894:
1895: public int compute_phase_step ( int choffs, int opoffs, opdata_cache cache, int lfo_raw_pm) {
1896:
1897:
1898:
1899:
1900:
1901: int delta = s_detune2_delta[op_detune2 (opoffs)];
1902:
1903:
1904: int pm_sensitivity = ch_lfo_pm_sens (choffs);
1905: if (pm_sensitivity != 0) {
1906:
1907:
1908:
1909:
1910:
1911: if (pm_sensitivity < 6) {
1912: delta += lfo_raw_pm >> (6 - pm_sensitivity);
1913: } else {
1914: delta += lfo_raw_pm << (pm_sensitivity - 5);
1915: }
1916: }
1917:
1918:
1919: int phase_step = opm_key_code_to_phase_step (cache.block_freq, delta);
1920:
1921:
1922: phase_step += cache.detune;
1923:
1924:
1925: return (phase_step * cache.multiple) >>> 1;
1926: }
1927:
1928:
1929: private int regbyte ( int offset, int start, int count) {
1930: return bitfield (m_regdata[offset + 0], start, count);
1931: }
1932: private int regbyte ( int offset, int start, int count, int extra_offset) {
1933: return bitfield (m_regdata[offset + extra_offset], start, count);
1934: }
1935:
1936:
1937: private int regword ( int offset1, int start1, int count1, int offset2, int start2, int count2) {
1938: return (regbyte (offset1, start1, count1, 0) << count2) | regbyte (offset2, start2, count2, 0);
1939: }
1940: private int regword ( int offset1, int start1, int count1, int offset2, int start2, int count2, int extra_offset) {
1941: return (regbyte (offset1, start1, count1, extra_offset) << count2) | regbyte (offset2, start2, count2, extra_offset);
1942: }
1943:
1944:
1945: public int test () {
1946: return regbyte (0x01, 0, 8);
1947: }
1948: public int lfo_reset () {
1949: return regbyte (0x01, 1, 1);
1950: }
1951: public int noise_frequency () {
1952: return regbyte (0x0f, 0, 5) ^ 0x1f;
1953: }
1954: public int noise_enable () {
1955: return regbyte (0x0f, 7, 1);
1956: }
1957: public int timer_a_value () {
1958: return regword (0x10, 0, 8, 0x11, 0, 2);
1959: }
1960: public int timer_b_value () {
1961: return regbyte (0x12, 0, 8);
1962: }
1963: public int csm () {
1964: return regbyte (0x14, 7, 1);
1965: }
1966: public int reset_timer_b () {
1967: return regbyte (0x14, 5, 1);
1968: }
1969: public int reset_timer_a () {
1970: return regbyte (0x14, 4, 1);
1971: }
1972: public int enable_timer_b () {
1973: return regbyte (0x14, 3, 1);
1974: }
1975: public int enable_timer_a () {
1976: return regbyte (0x14, 2, 1);
1977: }
1978: public int load_timer_b () {
1979: return regbyte (0x14, 1, 1);
1980: }
1981: public int load_timer_a () {
1982: return regbyte (0x14, 0, 1);
1983: }
1984: public int lfo_rate () {
1985: return regbyte (0x18, 0, 8);
1986: }
1987: public int lfo_am_depth () {
1988: return regbyte (0x19, 0, 7);
1989: }
1990: public int lfo_pm_depth () {
1991: return regbyte (0x1a, 0, 7);
1992: }
1993: public int output_bits () {
1994: return regbyte (0x1b, 6, 2);
1995: }
1996: public int lfo_waveform () {
1997: return regbyte (0x1b, 0, 2);
1998: }
1999:
2000:
2001: public int ch_output_any ( int choffs) {
2002: return regbyte (0x20, 6, 2, choffs);
2003: }
2004: public int ch_output_0 ( int choffs) {
2005: return regbyte (0x20, 6, 1, choffs);
2006: }
2007: public int ch_output_1 ( int choffs) {
2008: return regbyte (0x20, 7, 1, choffs);
2009: }
2010: public int ch_feedback ( int choffs) {
2011: return regbyte (0x20, 3, 3, choffs);
2012: }
2013: public int ch_algorithm ( int choffs) {
2014: return regbyte (0x20, 0, 3, choffs);
2015: }
2016: public int ch_block_freq ( int choffs) {
2017: return regword (0x28, 0, 7, 0x30, 2, 6, choffs);
2018: }
2019: public int ch_lfo_pm_sens ( int choffs) {
2020: return regbyte (0x38, 4, 3, choffs);
2021: }
2022: public int ch_lfo_am_sens ( int choffs) {
2023: return regbyte (0x38, 0, 2, choffs);
2024: }
2025:
2026:
2027: public int op_detune ( int opoffs) {
2028: return regbyte (0x40, 4, 3, opoffs);
2029: }
2030: public int op_multiple ( int opoffs) {
2031: return regbyte (0x40, 0, 4, opoffs);
2032: }
2033: public int op_total_level ( int opoffs) {
2034: return regbyte (0x60, 0, 7, opoffs);
2035: }
2036: public int op_ksr ( int opoffs) {
2037: return regbyte (0x80, 6, 2, opoffs);
2038: }
2039: public int op_attack_rate ( int opoffs) {
2040: return regbyte (0x80, 0, 5, opoffs);
2041: }
2042: public int op_lfo_am_enable ( int opoffs) {
2043: return regbyte (0xa0, 7, 1, opoffs);
2044: }
2045: public int op_decay_rate ( int opoffs) {
2046: return regbyte (0xa0, 0, 5, opoffs);
2047: }
2048: public int op_detune2 ( int opoffs) {
2049: return regbyte (0xc0, 6, 2, opoffs);
2050: }
2051: public int op_sustain_rate ( int opoffs) {
2052: return regbyte (0xc0, 0, 5, opoffs);
2053: }
2054: public int op_sustain_level ( int opoffs) {
2055: return regbyte (0xe0, 4, 4, opoffs);
2056: }
2057: public int op_release_rate ( int opoffs) {
2058: return regbyte (0xe0, 0, 4, opoffs);
2059: }
2060:
2061:
2062:
2063:
2064:
2065:
2066: static interface Listener {
2067:
2068:
2069:
2070:
2071:
2072:
2073:
2074:
2075:
2076:
2077:
2078:
2079:
2080:
2081:
2082:
2083:
2084:
2085:
2086:
2087:
2088:
2089:
2090:
2091:
2092:
2093:
2094:
2095:
2096:
2097:
2098:
2099: public void timerA (int clocks);
2100:
2101:
2102:
2103:
2104:
2105: public void timerB (int clocks);
2106:
2107:
2108:
2109:
2110:
2111:
2112:
2113:
2114:
2115:
2116: public void busy (int clocks);
2117:
2118:
2119:
2120:
2121:
2122:
2123:
2124:
2125:
2126:
2127: public boolean isBusy ();
2128:
2129:
2130:
2131:
2132:
2133:
2134:
2135:
2136:
2137:
2138:
2139:
2140:
2141:
2142: public void irq (boolean asserted);
2143:
2144:
2145:
2146:
2147:
2148:
2149:
2150:
2151:
2152:
2153:
2154:
2155: public void control (int data);
2156:
2157:
2158:
2159: public void written (int pointer, int address, int data);
2160:
2161: }
2162:
2163:
2164:
2165: private Listener listener;
2166: private int[] buffer;
2167: private int pointer;
2168: private int channelMask;
2169:
2170:
2171: private void init2 () {
2172: listener = null;
2173: buffer = new int[2 * 62500 * 5];
2174: pointer = 0;
2175: channelMask = ALL_CHANNELS;
2176: }
2177:
2178:
2179:
2180: public void setListener (Listener listener) {
2181: this.listener = listener;
2182: }
2183:
2184:
2185:
2186:
2187:
2188: public void allocate (int size) {
2189: buffer = new int[size];
2190: Arrays.fill (buffer, 0);
2191: pointer = 0;
2192: }
2193:
2194:
2195:
2196:
2197:
2198: public void clear () {
2199: Arrays.fill (buffer, 0);
2200: pointer = 0;
2201: }
2202:
2203:
2204:
2205: public int[] getBuffer () {
2206: return buffer;
2207: }
2208:
2209:
2210:
2211: public int getPointer () {
2212: return pointer;
2213: }
2214:
2215:
2216:
2217:
2218:
2219:
2220:
2221:
2222:
2223:
2224:
2225:
2226:
2227:
2228: public void fill () {
2229: generate (buffer.length);
2230: }
2231:
2232:
2233:
2234:
2235:
2236:
2237:
2238:
2239:
2240:
2241:
2242:
2243:
2244:
2245:
2246:
2247:
2248:
2249: public void setChannelMask (int mask) {
2250: channelMask = mask;
2251: }
2252:
2253:
2254:
2255: public void timerAExpired () {
2256: engine_timer_expired (0);
2257: }
2258:
2259:
2260:
2261: public void timerBExpired () {
2262: engine_timer_expired (1);
2263: }
2264:
2265:
2266:
2267: }