MercuryUnit.java
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13: package xeij;
14:
15: import java.util.*;
16:
17: public class MercuryUnit {
18:
19: public static final boolean MU4_ON = true;
20: public static boolean mu4OnRequest;
21: public static boolean mu4On;
22: public static boolean mu4OutputEnable;
23:
24: public static final boolean MU4_DEBUG = false;
25:
26:
27:
28: public static void mu4Init () {
29:
30: mu4OnRequest = Settings.sgsGetOnOff ("mercury");
31: mu4OutputEnable = Settings.sgsGetOnOff ("mercuryoe");
32:
33: mu4Hermite640 = new Hermite (640, 2500);
34: mu4Hermite882 = new Hermite (882, 2500);
35: mu4Hermite960 = new Hermite (960, 2500);
36: mu4Hermite1280 = new Hermite (1280, 2500);
37: mu4Hermite1764 = new Hermite (1764, 2500);
38: mu4Hermite1920 = new Hermite (1920, 2500);
39:
40: for (int i = 0; i <= MU4_ATTACK_FRAMES; i++) {
41: mu4AttackArray[i] =
42: (float) ((1.0 + Math.sin (Math.PI *
43: (double) (i - MU4_ATTACK_FRAMES / 2) /
44: (double) MU4_ATTACK_FRAMES)) / 2.0);
45: }
46: if (MU4_DEBUG) {
47: for (int i = 0; i <= MU4_ATTACK_FRAMES; i++) {
48: System.out.printf ("mu4AttackArray[%d]=%.6f\n", i, mu4AttackArray[i]);
49: }
50: }
51: }
52:
53:
54:
55: public static void mu4Tini () {
56:
57: Settings.sgsPutOnOff ("mercury", mu4OnRequest);
58: Settings.sgsPutOnOff ("mercuryoe", mu4OutputEnable);
59: }
60:
61:
62:
63: public static void mu4Reset () {
64: mu4On = mu4OnRequest;
65:
66:
67: mu4PortUpper = (MU4_U_RESERVED |
68: MU4_U12_TERR |
69:
70:
71: MU4_U6_INSEL);
72: mu4PortCommand = 0;
73: mu4PortStatus = (MU4_S3_N32K |
74: MU4_S2_N44K |
75: MU4_S1_N48K);
76:
77: mu4EnablePclReq = true;
78: mu4RiseExpcl ();
79: mu4RiseExreq ();
80: mu4EnablePclReq = false;
81: mu4SequenceArray = null;
82: Arrays.fill (mu4Buffer, 0);
83: TickerQueue.tkqRemove (mu4SequenceTicker);
84: mu4PortCommand = -1;
85: mu4SetCommand (MU4_U_RESERVED |
86: MU4_U12_TERR |
87: MU4_U11_EXPCL |
88: MU4_U10_EXREQ |
89: MU4_U6_INSEL);
90: }
91:
92:
93:
94: public static int mu4ReadByte (int a) {
95: int a70 = a & 0x70;
96: int d = 0;
97: if (a70 == 0x10) {
98: d = (a & 1) == 0 ? mu4PortUpper >> 8 : (mu4PortUpper | mu4PortCommand) & 0xff;
99: } else if (a70 == 0x20) {
100: d = (a & 1) == 0 ? mu4PortUpper >> 8 : (mu4PortUpper | mu4PortStatus) & 0xff;
101: }
102: if (MU4_DEBUG) {
103: System.out.printf ("%08x mu4ReadByte(0x%08x)=0x%02x\n", XEiJ.regPC0, a, d);
104: }
105: return d;
106: }
107:
108:
109:
110: public static int mu4ReadWord (int a) {
111: int a70 = a & 0x70;
112: int d = 0;
113: if (a70 == 0x10) {
114: d = mu4PortUpper | mu4PortCommand;
115: } else if (a70 == 0x20) {
116: d = mu4PortUpper | mu4PortStatus;
117: }
118: if (MU4_DEBUG) {
119: System.out.printf ("%08x mu4ReadWord(0x%08x)=0x%04x\n", XEiJ.regPC0, a, d);
120: }
121: return d;
122: }
123:
124:
125:
126: public static void mu4WriteByte (int a, int d) {
127: d &= 0xff;
128: if (MU4_DEBUG) {
129: System.out.printf ("%08x mu4WriteByte(0x%08x,0x%02x)\n", XEiJ.regPC0, a, d);
130: }
131: int a70 = a & 0x70;
132: if (a70 == 0x10) {
133: int t = mu4PortUpper | mu4PortCommand;
134: if ((a & 1) == 0) {
135: mu4SetCommand ((d << 8) | (t & 0xff));
136: } else {
137: mu4SetCommand ((t & 0xff00) | d);
138: }
139: }
140: }
141:
142:
143:
144: public static void mu4WriteWord (int a, int d) {
145: d &= 0xffff;
146: if (MU4_DEBUG) {
147: System.out.printf ("%08x mu4WriteWord(0x%08x,0x%04x)\n", XEiJ.regPC0, a, d);
148: }
149: int a70 = a & 0x70;
150: if (a70 == 0x00 &&
151: mu4Mode == MU4_MODE_OUT &&
152: mu4OutputEnable &&
153: 0 <= mu4WritePointer) {
154: if ((mu4DataChannels == 1 ||
155: (mu4WritePointer & 1) == 0) &&
156: (mu4PortCommand & MU4_C2_LG) != 0) {
157: mu4NaiKamoLeft = false;
158: if (mu4NaiDesuLeft) {
159: mu4NaiDesuLeft = false;
160: mu4AttackIndexLeft = 1;
161: }
162: mu4DataArray[mu4WritePointer] = Math.round (mu4AttackArray[mu4AttackIndexLeft] * (short) d);
163: mu4AttackIndexLeft = Math.min (MU4_ATTACK_FRAMES, mu4AttackIndexLeft + 1);
164: }
165: if ((mu4DataChannels == 1 ||
166: (mu4WritePointer & 1) != 0) &&
167: (mu4PortCommand & MU4_C3_RG) != 0) {
168: mu4NaiKamoRight = false;
169: if (mu4NaiDesuRight) {
170: mu4NaiDesuRight = false;
171: mu4AttackIndexRight = 1;
172: }
173: mu4DataArray[mu4WritePointer + (2 - mu4DataChannels)] = Math.round (mu4AttackArray[mu4AttackIndexRight] * (short) d);
174: mu4AttackIndexRight = Math.min (MU4_ATTACK_FRAMES, mu4AttackIndexRight + 1);
175: }
176: if (false) {
177: mu4WritePointer = -1;
178: }
179: mu4DataWritten = true;
180: } else if (a70 == 0x10) {
181: mu4SetCommand (d);
182: }
183: }
184:
185:
186:
187:
188:
189:
190: public static void mu4HsyncStart (long hsyncTime) {
191: if (mu4Mode != MU4_MODE_M256) {
192: return;
193: }
194: mu4SequenceArray = (mu4DataChannels == 1 ?
195: mu4DataRate < 32000 ? MU4_M256_LOW_MONO : MU4_M256_HIGH_MONO
196: :
197: mu4DataRate < 32000 ? MU4_M256_LOW_STEREO : MU4_M256_HIGH_STEREO);
198: if (mu4SequenceArray == MU4_M256_LOW_STEREO &&
199: (mu4PortUpper & MU4_U54_CLKSEL) == MU4_U54_32K) {
200: mu4SequenceArray = MU4_M256_LOW_MONO;
201: }
202:
203:
204:
205: mu4BlockTime = hsyncTime;
206:
207: mu4FrameNumber = 0;
208:
209: mu4SequenceIndex = 0;
210:
211: TickerQueue.tkqAdd (
212: mu4SequenceTicker,
213: mu4BlockTime +
214: mu4SequenceArray[mu4SequenceIndex++] *
215: XEiJ.TMR_FREQ / mu4DataFrequency);
216: }
217:
218:
219:
220:
221:
222: public static void mu4ExackStart () {
223: if ((mu4PortUpper & MU4_U8_ACKIG) != 0) {
224: mu4RiseExreq ();
225: }
226: }
227:
228:
229:
230:
231: public static final int[] mu4Buffer = new int[2 * 2500];
232:
233:
234:
235: public static void mu4FillBuffer () {
236: if (mu4Mode != MU4_MODE_OUT) {
237: return;
238: }
239: if (MU4_DEBUG) {
240: System.out.printf ("%08x mu4FillBuffer()\n", XEiJ.regPC0);
241: }
242:
243: mu4FrameNumber -= mu4DataFrames;
244:
245: mu4BlockTime += MU4_BLOCK_TIME;
246:
247: TickerQueue.tkqAdd (
248: mu4SequenceTicker,
249: mu4BlockTime +
250: (mu4DataCycles * mu4FrameNumber + mu4SequenceArray[mu4SequenceIndex - 1]) *
251: XEiJ.TMR_FREQ / mu4DataFrequency);
252:
253: if (!mu4DataWritten) {
254: Arrays.fill (mu4Buffer, 0);
255: return;
256: }
257: mu4DataWritten = false;
258:
259: switch (mu4DataFrames) {
260: case 640:
261: mu4Hermite640.convert ();
262: break;
263: case 882:
264: mu4Hermite882.convert ();
265: break;
266: case 960:
267: mu4Hermite960.convert ();
268: break;
269: case 1280:
270: mu4Hermite1280.convert ();
271: break;
272: case 1764:
273: mu4Hermite1764.convert ();
274: break;
275: case 1920:
276: mu4Hermite1920.convert ();
277: break;
278: }
279:
280: for (int i = 0; i < 2 * 4; i++) {
281: mu4DataArray[i] = mu4DataArray[2 * mu4DataFrames + i];
282: mu4DataWritten = mu4DataWritten || mu4DataArray[i] != 0;
283: }
284: Arrays.fill (mu4DataArray, 2 * 4, 2 * (mu4DataFrames + 4), 0);
285: }
286:
287:
288:
289:
290:
291: static final int MU4_U_RESERVED = 7 << 13;
292: static final int MU4_U12_TERR = 1 << 12;
293: static final int MU4_U11_EXPCL = 1 << 11;
294: static final int MU4_U10_EXREQ = 1 << 10;
295: static final int MU4_U9_M256 = 1 << 9;
296: static final int MU4_U8_ACKIG = 1 << 8;
297: static final int MU4_U7_CLKRATE = 1 << 7;
298: static final int MU4_U6_INSEL = 1 << 6;
299: static final int MU4_U54_CLKSEL = 3 << 4;
300: static final int MU4_U54_32K = 1 << 4;
301: static final int MU4_U54_48K = 3 << 4;
302:
303: static final int MU4_C3_RG = 1 << 3;
304: static final int MU4_C2_LG = 1 << 2;
305: static final int MU4_C1_STEREO = 1 << 1;
306: static final int MU4_C0_OUT = 1 << 0;
307:
308: static final int MU4_S3_N32K = 1 << 3;
309: static final int MU4_S2_N44K = 1 << 2;
310: static final int MU4_S1_N48K = 1 << 1;
311: static final int MU4_S0_ERR = 1 << 0;
312:
313: static int mu4PortUpper;
314: static int mu4PortCommand;
315: static int mu4PortStatus;
316:
317:
318: static final int MU4_MODE_M256 = 0;
319: static final int MU4_MODE_OUT = 1;
320: static final int MU4_MODE_IN = 2;
321: static int mu4Mode;
322:
323:
324: static boolean mu4EnablePclReq;
325:
326:
327: static int mu4DataFrequency;
328:
329:
330: static int mu4DataCycles;
331:
332:
333:
334: static int mu4DataRate;
335:
336:
337: static int mu4DataChannels;
338:
339:
340:
341: static final int MU4_BLOCK_RATE = 25;
342:
343:
344:
345: static int mu4DataFrames;
346:
347:
348:
349: static final int MU4_LINE_RATE = 62500;
350:
351:
352:
353: static final int MU4_LINE_CHANNELS = 2;
354:
355:
356:
357: static final int MU4_LINE_FRAMES = MU4_LINE_RATE / MU4_BLOCK_RATE;
358:
359:
360:
361: static final int MU4_LINE_ELEMENTS = MU4_LINE_CHANNELS * MU4_LINE_FRAMES;
362:
363:
364:
365:
366:
367:
368: static final int MU4_FALL_EXPCL = 0;
369: static final int MU4_RISE_EXPCL = 1;
370: static final int MU4_FALL_EXREQ = 2;
371: static final int MU4_RISE_EXREQ = 3;
372:
373:
374:
375:
376: static final int[] MU4_M256_LOW_MONO = {
377: 2, MU4_FALL_EXPCL,
378: 20, MU4_FALL_EXREQ,
379: 283, MU4_RISE_EXREQ,
380: 385, MU4_RISE_EXPCL,
381: };
382:
383:
384: static final int[] MU4_M256_LOW_STEREO = {
385: 2, MU4_FALL_EXPCL,
386: 283, MU4_RISE_EXREQ,
387: 385, MU4_RISE_EXPCL,
388: 404, MU4_FALL_EXREQ,
389: };
390:
391:
392:
393: static final int[] MU4_M256_HIGH_MONO = {
394: 2, MU4_FALL_EXPCL,
395: 10, MU4_FALL_EXREQ,
396: 142, MU4_RISE_EXREQ,
397: 193, MU4_RISE_EXPCL,
398: };
399:
400:
401:
402: static final int[] MU4_M256_HIGH_STEREO = {
403: 2, MU4_FALL_EXPCL,
404: 10, MU4_FALL_EXREQ,
405: 142, MU4_RISE_EXREQ,
406: 193, MU4_RISE_EXPCL,
407: 202, MU4_FALL_EXREQ,
408: 334, MU4_RISE_EXREQ,
409: };
410:
411:
412:
413: static final int[] MU4_OUT_LOW_MONO = {
414: 0, MU4_FALL_EXPCL,
415: 379, MU4_FALL_EXREQ,
416: 384, MU4_RISE_EXPCL,
417: 667, MU4_RISE_EXREQ,
418: };
419:
420:
421:
422: static final int[] MU4_OUT_LOW_STEREO = {
423: 0, MU4_FALL_EXPCL,
424: 283, MU4_RISE_EXREQ,
425: 379, MU4_FALL_EXREQ,
426: 384, MU4_RISE_EXPCL,
427: 667, MU4_RISE_EXREQ,
428: 763, MU4_FALL_EXREQ,
429: };
430:
431:
432:
433: static final int[] MU4_OUT_HIGH_MONO = {
434: 0, MU4_FALL_EXPCL,
435: 190, MU4_FALL_EXREQ,
436: 192, MU4_RISE_EXPCL,
437: 334, MU4_RISE_EXREQ,
438: };
439:
440:
441:
442: static final int[] MU4_OUT_HIGH_STEREO = {
443: 0, MU4_FALL_EXPCL,
444: 142, MU4_RISE_EXREQ,
445: 190, MU4_FALL_EXREQ,
446: 192, MU4_RISE_EXPCL,
447: 334, MU4_RISE_EXREQ,
448: 382, MU4_FALL_EXREQ,
449: };
450:
451:
452: static int[] mu4SequenceArray;
453:
454:
455:
456: static final long MU4_BLOCK_TIME = XEiJ.TMR_FREQ / MU4_BLOCK_RATE;
457:
458:
459:
460:
461: static long mu4BlockTime;
462:
463:
464:
465:
466: static int mu4FrameNumber;
467:
468:
469: static int mu4SequenceIndex;
470:
471:
472:
473:
474: static int mu4LRCounter;
475:
476:
477:
478:
479: static int mu4WritePointer;
480:
481:
482:
483:
484: static final int[] mu4DataArray = new int[2 * (1920 + 4)];
485:
486:
487: static boolean mu4DataWritten;
488:
489:
490:
491: static void mu4DumpVars () {
492: System.out.printf ("mu4Mode=%d\n", mu4Mode);
493: System.out.printf ("mu4EnablePclReq=%b\n", mu4EnablePclReq);
494: System.out.printf ("mu4DataFrequency=%d\n", mu4DataFrequency);
495: System.out.printf ("mu4DataCycles=%d\n", mu4DataCycles);
496: System.out.printf ("mu4DataRate=%d\n", mu4DataRate);
497: System.out.printf ("mu4DataChannels=%d\n", mu4DataChannels);
498: System.out.printf ("mu4DataFrames=%d\n", mu4DataFrames);
499: System.out.printf ("mu4BlockTime=%d\n", mu4BlockTime);
500: System.out.printf ("mu4FrameNumber=%d\n", mu4FrameNumber);
501: System.out.printf ("mu4SequenceIndex=%d\n", mu4SequenceIndex);
502: System.out.printf ("mu4LRCounter=%d\n", mu4LRCounter);
503: System.out.printf ("mu4WritePointer=%d\n", mu4WritePointer);
504: System.out.printf ("mu4DataWritten=%b\n", mu4DataWritten);
505: }
506:
507:
508:
509: static void mu4SetCommand (int d) {
510: if (MU4_DEBUG) {
511: System.out.printf ("%08x mu4SetCommand(0x%04x)\n", XEiJ.regPC0, d);
512: }
513: int prevMode = mu4Mode;
514: int prevDataRate = mu4DataRate;
515: int prevDataChannels = mu4DataChannels;
516: int prevUpper = mu4PortUpper;
517: int prevCommand = mu4PortCommand;
518: mu4PortUpper = ((mu4PortUpper & (MU4_U_RESERVED |
519: MU4_U12_TERR |
520: MU4_U11_EXPCL |
521: MU4_U10_EXREQ)) |
522: (d & (MU4_U9_M256 |
523: MU4_U8_ACKIG |
524: MU4_U7_CLKRATE |
525: MU4_U6_INSEL |
526: MU4_U54_CLKSEL)));
527: mu4PortCommand = d & (MU4_C3_RG |
528: MU4_C2_LG |
529: MU4_C1_STEREO |
530: MU4_C0_OUT);
531:
532:
533: mu4EnablePclReq = (mu4PortUpper & (MU4_U9_M256 | MU4_U8_ACKIG)) != 0;
534:
535: if ((((mu4PortUpper | mu4PortCommand) ^ (prevUpper | prevCommand)) & 0xff) == 0) {
536: return;
537: }
538:
539: mu4Mode = ((mu4PortUpper & MU4_U9_M256) == 0 ? MU4_MODE_M256 :
540: (mu4PortCommand & MU4_C0_OUT) != 0 ? MU4_MODE_OUT :
541: MU4_MODE_IN);
542:
543: mu4DataFrequency = ((mu4PortUpper & MU4_U54_CLKSEL) == MU4_U54_32K ? 12288000 :
544: (mu4PortUpper & MU4_U54_CLKSEL) != MU4_U54_48K ? 16934400 :
545: 18432000);
546:
547: mu4DataCycles = (mu4PortUpper & MU4_U7_CLKRATE) == 0 ? 768 : 384;
548:
549: mu4DataRate = mu4DataFrequency / mu4DataCycles;
550:
551: mu4DataChannels = (mu4PortCommand & MU4_C1_STEREO) == 0 ? 1 : 2;
552:
553: if (mu4Mode != prevMode ||
554: mu4DataRate != prevDataRate ||
555: mu4DataChannels != prevDataChannels) {
556: if (mu4Mode == MU4_MODE_M256) {
557:
558: mu4SequenceArray = null;
559: } else if (mu4Mode == MU4_MODE_OUT) {
560:
561: mu4DataFrames = mu4DataRate / MU4_BLOCK_RATE;
562:
563: mu4SequenceArray = (mu4DataChannels == 1 ?
564: mu4DataRate < 32000 ? MU4_OUT_LOW_MONO : MU4_OUT_HIGH_MONO
565: :
566: mu4DataRate < 32000 ? MU4_OUT_LOW_STEREO : MU4_OUT_HIGH_STEREO);
567:
568: mu4BlockTime = SoundSource.sndBlockClock - MU4_BLOCK_TIME;
569:
570:
571: mu4FrameNumber =
572: Math.max (0,
573: Math.min (mu4DataFrames,
574: (int) (((XEiJ.mpuClockTime - mu4BlockTime) * mu4DataFrames +
575: (MU4_BLOCK_TIME - 1)) / MU4_BLOCK_TIME)));
576:
577: mu4SequenceIndex = 0;
578:
579: mu4LRCounter = 0;
580:
581: mu4WritePointer = -1;
582: if (mu4DataRate != prevDataRate ||
583: mu4DataChannels != prevDataChannels) {
584:
585: Arrays.fill (mu4DataArray, 0, 2 * (mu4DataFrames + 4), 0);
586: }
587:
588: mu4DataWritten = false;
589: if (MU4_DEBUG) {
590: mu4DumpVars ();
591: }
592:
593: mu4AttackIndexLeft = 1;
594: mu4AttackIndexRight = 1;
595: mu4NaiKamoLeft = true;
596: mu4NaiKamoRight = true;
597: mu4NaiDesuLeft = true;
598: mu4NaiDesuRight = true;
599:
600: TickerQueue.tkqAdd (
601: mu4SequenceTicker,
602: mu4BlockTime +
603: (mu4DataCycles * mu4FrameNumber + mu4SequenceArray[mu4SequenceIndex++]) *
604: XEiJ.TMR_FREQ / mu4DataFrequency);
605: } else {
606:
607: mu4SequenceArray = null;
608: }
609: }
610: }
611:
612:
613:
614: static final TickerQueue.Ticker mu4SequenceTicker = new TickerQueue.Ticker () {
615: @Override protected void tick () {
616: if (mu4SequenceArray == null) {
617: return;
618: }
619: switch (mu4SequenceArray[mu4SequenceIndex++]) {
620: case MU4_FALL_EXPCL:
621: mu4FallExpcl ();
622: break;
623: case MU4_RISE_EXPCL:
624: mu4RiseExpcl ();
625: break;
626: case MU4_FALL_EXREQ:
627: if (mu4Mode == MU4_MODE_OUT) {
628:
629: mu4WritePointer = 2 * (mu4FrameNumber + 3) + mu4LRCounter;
630:
631: mu4LRCounter ^= 1;
632:
633: mu4DataArray[mu4WritePointer] = (int) (mu4DataArray[mu4WritePointer - 2] * MU4_DECAY_RATIO);
634: if (mu4DataChannels == 1 ||
635: (mu4WritePointer & 1) == 0) {
636: mu4NaiDesuLeft = mu4NaiDesuLeft || mu4NaiKamoLeft;
637: mu4NaiKamoLeft = true;
638: }
639: if (mu4DataChannels == 1 ||
640: (mu4WritePointer & 1) != 0) {
641: mu4NaiDesuRight = mu4NaiDesuRight || mu4NaiKamoRight;
642: mu4NaiKamoRight = true;
643: }
644: }
645: mu4FallExreq ();
646: break;
647: case MU4_RISE_EXREQ:
648: mu4RiseExreq ();
649: break;
650: }
651: if (mu4SequenceArray.length <= mu4SequenceIndex) {
652: if (mu4Mode == MU4_MODE_M256) {
653: mu4SequenceArray = null;
654: return;
655: }
656:
657: mu4FrameNumber++;
658: mu4SequenceIndex = 0;
659: mu4LRCounter = 0;
660: }
661:
662: TickerQueue.tkqAdd (
663: mu4SequenceTicker,
664: mu4BlockTime +
665: (mu4DataCycles * mu4FrameNumber + mu4SequenceArray[mu4SequenceIndex++]) *
666: XEiJ.TMR_FREQ / mu4DataFrequency);
667: }
668: };
669:
670:
671:
672: static void mu4FallExpcl () {
673: if ((mu4PortUpper & MU4_U11_EXPCL) != 0) {
674: mu4PortUpper &= ~MU4_U11_EXPCL;
675: if (mu4EnablePclReq) {
676: HD63450.dmaFallPCL (2);
677: }
678: }
679: }
680:
681:
682:
683: static void mu4RiseExpcl () {
684: if ((mu4PortUpper & MU4_U11_EXPCL) == 0) {
685: mu4PortUpper |= MU4_U11_EXPCL;
686: if (mu4EnablePclReq) {
687: HD63450.dmaRisePCL (2);
688: }
689: }
690: }
691:
692:
693:
694: static void mu4FallExreq () {
695: if ((mu4PortUpper & MU4_U10_EXREQ) != 0) {
696: mu4PortUpper &= ~MU4_U10_EXREQ;
697: if (mu4EnablePclReq) {
698: HD63450.dmaFallREQ (2);
699: }
700: }
701: }
702:
703:
704:
705: static void mu4RiseExreq () {
706: if ((mu4PortUpper & MU4_U10_EXREQ) == 0) {
707: mu4PortUpper |= MU4_U10_EXREQ;
708: if (mu4EnablePclReq) {
709: HD63450.dmaRiseREQ (2);
710: }
711: }
712: }
713:
714:
715:
716:
717: static Hermite mu4Hermite640;
718: static Hermite mu4Hermite882;
719: static Hermite mu4Hermite960;
720: static Hermite mu4Hermite1280;
721: static Hermite mu4Hermite1764;
722: static Hermite mu4Hermite1920;
723:
724:
725:
726: static class Hermite {
727: int inputFrames, outputFrames;
728: int inputFactor, outputFactor;
729: float[] coeffArray;
730: int[] indexArray;
731: Hermite (int inputFrames, int outputFrames) {
732: this.inputFrames = inputFrames;
733: this.outputFrames = outputFrames;
734: int g = gcd (inputFrames, outputFrames);
735: inputFactor = inputFrames / g;
736: outputFactor = outputFrames / g;
737: coeffArray = new float[4 * outputFactor];
738: indexArray = new int[outputFactor];
739: int inputIndex1 = 0;
740: int ratio1 = 0;
741: for (int outputIndex = 0; outputIndex < outputFactor; outputIndex++) {
742: int inputIndex0 = inputIndex1;
743: int ratio0 = ratio1;
744: ratio1 += inputFactor;
745: while (outputFactor <= ratio1) {
746: ratio1 -= outputFactor;
747: inputIndex1++;
748: }
749:
750:
751:
752:
753:
754:
755:
756:
757:
758:
759:
760:
761:
762:
763:
764:
765:
766:
767:
768:
769:
770:
771:
772:
773:
774:
775:
776:
777:
778:
779:
780:
781:
782: double x = (double) ratio0 / (double) outputFactor;
783: coeffArray[4 * outputIndex] = (float) (((-0.5 * x + 1.0) * x - 0.5) * x);
784: coeffArray[4 * outputIndex + 1] = (float) ((1.5 * x - 2.5) * x * x + 1.0);
785: coeffArray[4 * outputIndex + 2] = (float) (((-1.5 * x + 2.0) * x + 0.5) * x);
786: coeffArray[4 * outputIndex + 3] = (float) ((0.5 * x - 0.5) * x * x);
787: indexArray[outputIndex] = inputIndex0;
788: }
789: }
790: void convert () {
791: for (int inputIndex = 0, outputIndex = 0;
792: inputIndex < inputFrames;
793: inputIndex += inputFactor, outputIndex += outputFactor) {
794: for (int od = 0; od < outputFactor; od++) {
795: int ii = inputIndex + indexArray[od];
796: int oi = outputIndex + od;
797: float cm = coeffArray[4 * od];
798: float c0 = coeffArray[4 * od + 1];
799: float c1 = coeffArray[4 * od + 2];
800: float c2 = coeffArray[4 * od + 3];
801: mu4Buffer[2 * oi + 0] = Math.round (cm * mu4DataArray[2 * ii + 0] +
802: c0 * mu4DataArray[2 * ii + 2] +
803: c1 * mu4DataArray[2 * ii + 4] +
804: c2 * mu4DataArray[2 * ii + 6]);
805: mu4Buffer[2 * oi + 1] = Math.round (cm * mu4DataArray[2 * ii + 1] +
806: c0 * mu4DataArray[2 * ii + 3] +
807: c1 * mu4DataArray[2 * ii + 5] +
808: c2 * mu4DataArray[2 * ii + 7]);
809: }
810: }
811: }
812: int gcd (int x, int y) {
813: while (y != 0) {
814: int t = x % y;
815: x = y;
816: y = t;
817: }
818: return x;
819: }
820: }
821:
822:
823:
824:
825:
826:
827:
828:
829: static final float MU4_DECAY_RATIO = 0.97F;
830: static final int MU4_ATTACK_FRAMES = 300;
831: static final float mu4AttackArray[] = new float[MU4_ATTACK_FRAMES + 1];
832: static int mu4AttackIndexLeft;
833: static int mu4AttackIndexRight;
834: static boolean mu4NaiKamoLeft;
835: static boolean mu4NaiKamoRight;
836: static boolean mu4NaiDesuLeft;
837: static boolean mu4NaiDesuRight;
838:
839:
840:
841: }