|
|
| version 1.8, 2004/02/03 08:24:40 | version 1.9, 2004/02/19 03:04:01 |
|---|---|
| Line 1 | Line 1 |
| #include "compiler.h" | #include "compiler.h" |
| #include <math.h> | |
| #include "pccore.h" | #include "pccore.h" |
| #include "iocore.h" | #include "iocore.h" |
| #include "cbuscore.h" | #include "cbuscore.h" |
| Line 7 | Line 8 |
| #include "fmboard.h" | #include "fmboard.h" |
| // ないよりあったほーが良い程度のリズム… | |
| static struct { | |
| PMIXHDR hdr; | |
| PMIXTRK trk[4]; | |
| } amd98r; | |
| static void pcmmake1(PMIXDAT *dat, UINT rate, | |
| int vol, double hz, double env) { | |
| UINT i; | |
| double x; | |
| double y; | |
| double slast; | |
| double s; | |
| double v; | |
| UINT size; | |
| SINT16 *ptr; | |
| x = 44100.0 * 2.0 * PI / ((double)rate * hz); | |
| y = 44100.0 / 256.0 / (double)rate; | |
| slast = 0.0; | |
| for (i=0; i<rate; i++) { | |
| s = sin(x * (double)i); | |
| v = pow(env, (double)i * y) * (double)vol; | |
| if ((v < 128.0) && (slast < 0.0) && (s >= 0.0)) { | |
| break; | |
| } | |
| slast = s; | |
| } | |
| size = i; | |
| if (!size) { | |
| return; | |
| } | |
| ptr = (SINT16 *)_MALLOC(size * sizeof(SINT16), "AMD98"); | |
| if (ptr == NULL) { | |
| return; | |
| } | |
| for (i=0; i<size; i++) { | |
| s = sin(x * (double)i); | |
| v = pow(env, (double)i * y) * (double)vol; | |
| ptr[i] = (SINT16)(s * v); | |
| } | |
| dat->sample = ptr; | |
| dat->samples = size; | |
| } | |
| static void pcmmake2(PMIXDAT *dat, UINT rate, | |
| int vol, double hz, double env, double k) { | |
| UINT i; | |
| double x; | |
| double y; | |
| double p; | |
| double s; | |
| double slast; | |
| double v; | |
| UINT size; | |
| SINT16 *ptr; | |
| x = 2.0 * PI * hz / (double)rate; | |
| y = 44100.0 / 256.0 / (double)rate; | |
| p = 0.0; | |
| slast = 0.0; | |
| for (i=0; i<rate; i++) { | |
| p += x * pow(k, (double)i * y); | |
| s = sin(p); | |
| v = pow(env, (double)i * y) * (double)vol; | |
| if ((v < 128.0) && (slast < 0.0) && (s >= 0.0)) { | |
| break; | |
| } | |
| slast = s; | |
| } | |
| size = i; | |
| if (!size) { | |
| return; | |
| } | |
| ptr = (SINT16 *)_MALLOC(size * sizeof(SINT16), "AMD98"); | |
| if (ptr == NULL) { | |
| return; | |
| } | |
| p = 0.0; | |
| for (i=0; i<size; i++) { | |
| p += x * pow(k, (double)i * y); | |
| s = sin(p); | |
| v = pow(env, (double)i * y) * (double)vol; | |
| ptr[i] = (SINT16)(s * v); | |
| } | |
| dat->sample = ptr; | |
| dat->samples = size; | |
| } | |
| void amd98_initialize(UINT rate) { | |
| UINT i; | |
| ZeroMemory(&amd98r, sizeof(amd98r)); | |
| amd98r.hdr.enable = 0x0f; | |
| // bd | |
| pcmmake1(&amd98r.trk[0].data, rate, | |
| 24000, 889.0476190476, 0.9446717478); | |
| // lt | |
| pcmmake2(&amd98r.trk[1].data, rate, | |
| 6400, 172.9411764706, 0.8665145391, 0.9960000000); | |
| // ht | |
| pcmmake2(&amd98r.trk[2].data, rate, | |
| 9600, 213.0000000000, 0.8665145391, 0.9960000000); | |
| // sd | |
| pcmmake1(&amd98r.trk[3].data, rate, | |
| 12000, 255.4400000000, 0.8538230481); | |
| for (i=0; i<4; i++) { | |
| amd98r.trk[i].flag = PMIXFLAG_L | PMIXFLAG_R; | |
| amd98r.trk[i].volume = 1 << 12; | |
| } | |
| } | |
| void amd98_deinitialize(void) { | |
| int i; | |
| void *ptr; | |
| for (i=0; i<4; i++) { | |
| ptr = amd98r.trk[i].data.sample; | |
| amd98r.trk[i].data.sample = NULL; | |
| if (ptr) { | |
| _MFREE(ptr); | |
| } | |
| } | |
| } | |
| static void amd98_rhythm(UINT map) { | |
| PMIXTRK *trk; | |
| UINT bit; | |
| map &= 0x0f; | |
| if (map == 0) { | |
| return; | |
| } | |
| sound_sync(); | |
| trk = amd98r.trk; | |
| bit = 0x01; | |
| do { | |
| if ((map & bit) && (trk->data.sample)) { | |
| trk->pcm = trk->data.sample; | |
| trk->remain = trk->data.samples; | |
| amd98r.hdr.playing |= bit; | |
| } | |
| trk++; | |
| bit <<= 1; | |
| } while (bit < 0x10); | |
| } | |
| // ---- | |
| static void setamd98event(BOOL absolute) { | static void setamd98event(BOOL absolute) { |
| SINT32 cnt; | SINT32 cnt; |
| Line 78 static void IOOUTCALL amd_odb(UINT port, | Line 236 static void IOOUTCALL amd_odb(UINT port, |
| else if (b == 0x40) { | else if (b == 0x40) { |
| // TRACEOUT(0xfff1, psg_1.reg.io2); | // TRACEOUT(0xfff1, psg_1.reg.io2); |
| if (amd98.psg3reg < 0x0e) { | if (amd98.psg3reg < 0x0e) { |
| psggen_setreg(&psg3, amd98.psg3reg, | psggen_setreg(&psg3, amd98.psg3reg, psg1.reg.io2); |
| psg1.reg.io2); | |
| } | } |
| #if 0 | |
| else if (amd98.psg3reg == 0x0f) { | else if (amd98.psg3reg == 0x0f) { |
| int r; | amd98_rhythm(psg1.reg.io2); |
| static const BYTE amdr[] = {0x01, 0x08, 0x10, 0x20, 0x06, 0x40}; | |
| sound_sync(); | |
| for (r=0; r<6; r++) { | |
| if (psg1.reg.io2 & amdr[r]) { | |
| // rhythm_play(&rhythm, r, 0); | |
| } | |
| } | |
| } | } |
| #endif | |
| } | } |
| } | } |
| psg2.reg.io2 = dat; | psg2.reg.io2 = dat; |
| Line 134 void amd98_bind(void) { | Line 282 void amd98_bind(void) { |
| sound_streamregist(&psg1, (SOUNDCB)psggen_getpcm); | sound_streamregist(&psg1, (SOUNDCB)psggen_getpcm); |
| sound_streamregist(&psg2, (SOUNDCB)psggen_getpcm); | sound_streamregist(&psg2, (SOUNDCB)psggen_getpcm); |
| sound_streamregist(&psg3, (SOUNDCB)psggen_getpcm); | sound_streamregist(&psg3, (SOUNDCB)psggen_getpcm); |
| // sound_streamregist(&rhythm, (SOUNDCB)rhythm_getpcm); | sound_streamregist(&amd98r, (SOUNDCB)pcmmix_getpcm); |
| iocore_attachout(0xd8, amd_od8); | iocore_attachout(0xd8, amd_od8); |
| iocore_attachout(0xd9, amd_od9); | iocore_attachout(0xd9, amd_od9); |
| iocore_attachout(0xda, amd_oda); | iocore_attachout(0xda, amd_oda); |