|
|
| version 1.1, 2003/10/16 17:58:04 | version 1.4, 2003/10/22 14:13:25 |
|---|---|
| Line 1 | Line 1 |
| #include "compiler.h" | #include "compiler.h" |
| #include <math.h> | #include <math.h> |
| #include "pccore.h" | |
| #include "iocore.h" | |
| #include "sound.h" | #include "sound.h" |
| #include "opngen.h" | #include "fmboard.h" |
| #include "keydisp.h" | #include "keydisp.h" |
| Line 15 | Line 17 |
| #define FREQBASE4096 ((double)OPNA_CLOCK / calcrate / 64) | #define FREQBASE4096 ((double)OPNA_CLOCK / calcrate / 64) |
| OPNCFG opncfg; | |
| SINT32 env_curve[EVC_ENT*2 + 1]; | SINT32 env_curve[EVC_ENT*2 + 1]; |
| SINT32 envtable[EVC_ENT]; | SINT32 envtable[EVC_ENT]; |
| SINT32 sintable[SIN_ENT]; | SINT32 sintable[SIN_ENT]; |
| #ifdef SOUND_FM_ASM | #ifdef OPNGENX86 |
| char envshift[EVC_ENT]; | char envshift[EVC_ENT]; |
| char sinshift[SIN_ENT]; | char sinshift[SIN_ENT]; |
| #endif | #endif |
| BYTE baseratebit; | |
| OPNCH opnch[OPNCH_MAX]; | |
| BYTE fm_keyreg[OPNCH_MAX]; | |
| UINT playchannels; | |
| SINT32 feedback2; | |
| SINT32 feedback3; | |
| SINT32 feedback4; | |
| SINT32 outdl; | |
| SINT32 outdc; | |
| SINT32 outdr; | |
| SINT32 calc1024; | |
| SINT32 calcremain; | |
| SINT32 fmvolforasm; | |
| SINT32 fmvolforc; | |
| static SINT32 detunetable[8][32]; | static SINT32 detunetable[8][32]; |
| Line 76 void opngen_initialize(UINT rate) { | Line 63 void opngen_initialize(UINT rate) { |
| calcrate = rate * 55466 / 44100; | calcrate = rate * 55466 / 44100; |
| calc1024 = FMDIV_ENT * 44100 / 55466; | opncfg.calc1024 = FMDIV_ENT * 44100 / 55466; |
| for (i=0; i<EVC_ENT; i++) { | for (i=0; i<EVC_ENT; i++) { |
| #ifdef SOUND_FM_ASM | #ifdef OPNGENX86 |
| char sft; | char sft; |
| sft = ENVTBL_BIT; | sft = ENVTBL_BIT; |
| while(sft < (ENVTBL_BIT + 8)) { | while(sft < (ENVTBL_BIT + 8)) { |
| Line 97 void opngen_initialize(UINT rate) { | Line 84 void opngen_initialize(UINT rate) { |
| #endif | #endif |
| } | } |
| for (i=0; i<SIN_ENT; i++) { | for (i=0; i<SIN_ENT; i++) { |
| #ifdef SOUND_FM_ASM | #ifdef OPNGENX86 |
| char sft; | char sft; |
| sft = SINTBL_BIT; | sft = SINTBL_BIT; |
| while(sft < (SINTBL_BIT + 8)) { | while(sft < (SINTBL_BIT + 8)) { |
| Line 129 void opngen_initialize(UINT rate) { | Line 116 void opngen_initialize(UINT rate) { |
| // ここで FREQ_BITS >= 16が条件 | // ここで FREQ_BITS >= 16が条件 |
| if (rate == 44100) { | if (rate == 44100) { |
| baseratebit = 0 + (FREQ_BITS - 16); | opncfg.ratebit = 0 + (FREQ_BITS - 16); |
| } | } |
| else if (rate == 22050) { | else if (rate == 22050) { |
| baseratebit = 1 + (FREQ_BITS - 16); | opncfg.ratebit = 1 + (FREQ_BITS - 16); |
| } | } |
| else { | else { |
| baseratebit = 2 + (FREQ_BITS - 16); | opncfg.ratebit = 2 + (FREQ_BITS - 16); |
| } | } |
| for (i=0; i<4; i++) { | for (i=0; i<4; i++) { |
| Line 176 void opngen_initialize(UINT rate) { | Line 163 void opngen_initialize(UINT rate) { |
| void opngen_setvol(UINT vol) { | void opngen_setvol(UINT vol) { |
| fmvolforc = vol * 5 / 4; | opncfg.fmvol = vol * 5 / 4; |
| fmvolforasm = fmvolforc << FMASMSHIFT; | #if defined(OPNGENX86) |
| opncfg.fmvol <<= FMASMSHIFT; | |
| #endif | |
| } | |
| void opngen_setVR(BYTE channel, BYTE value) { | |
| if ((channel & 3) && (value)) { | |
| opncfg.vr_en = TRUE; | |
| opncfg.vr_l = (channel & 1)?value:0; | |
| opncfg.vr_r = (channel & 2)?value:0; | |
| } | |
| else { | |
| opncfg.vr_en = FALSE; | |
| } | |
| } | } |
| Line 187 static void set_algorithm(OPNCH *ch) { | Line 188 static void set_algorithm(OPNCH *ch) { |
| SINT32 *outd; | SINT32 *outd; |
| outd = &outdc; | outd = &opngen.outdc; |
| if (ch->stereo) { | if (ch->stereo) { |
| switch(ch->pan & 0xc0) { | switch(ch->pan & 0xc0) { |
| case 0x80: | case 0x80: |
| outd = &outdl; | outd = &opngen.outdl; |
| break; | break; |
| case 0x40: | case 0x40: |
| outd = &outdr; | outd = &opngen.outdr; |
| break; | break; |
| } | } |
| } | } |
| switch(ch->algorithm) { | switch(ch->algorithm) { |
| case 0: | case 0: |
| ch->connect1 = &feedback2; | ch->connect1 = &opngen.feedback2; |
| ch->connect2 = &feedback3; | ch->connect2 = &opngen.feedback3; |
| ch->connect3 = &feedback4; | ch->connect3 = &opngen.feedback4; |
| break; | break; |
| case 1: | case 1: |
| ch->connect1 = &feedback3; | ch->connect1 = &opngen.feedback3; |
| ch->connect2 = &feedback3; | ch->connect2 = &opngen.feedback3; |
| ch->connect3 = &feedback4; | ch->connect3 = &opngen.feedback4; |
| break; | break; |
| case 2: | case 2: |
| ch->connect1 = &feedback4; | ch->connect1 = &opngen.feedback4; |
| ch->connect2 = &feedback3; | ch->connect2 = &opngen.feedback3; |
| ch->connect3 = &feedback4; | ch->connect3 = &opngen.feedback4; |
| break; | break; |
| case 3: | case 3: |
| ch->connect1 = &feedback2; | ch->connect1 = &opngen.feedback2; |
| ch->connect2 = &feedback4; | ch->connect2 = &opngen.feedback4; |
| ch->connect3 = &feedback4; | ch->connect3 = &opngen.feedback4; |
| break; | break; |
| case 4: | case 4: |
| ch->connect1 = &feedback2; | ch->connect1 = &opngen.feedback2; |
| ch->connect2 = outd; | ch->connect2 = outd; |
| ch->connect3 = &feedback4; | ch->connect3 = &opngen.feedback4; |
| break; | break; |
| case 5: | case 5: |
| Line 237 static void set_algorithm(OPNCH *ch) { | Line 238 static void set_algorithm(OPNCH *ch) { |
| break; | break; |
| case 6: | case 6: |
| ch->connect1 = &feedback2; | ch->connect1 = &opngen.feedback2; |
| ch->connect2 = outd; | ch->connect2 = outd; |
| ch->connect3 = outd; | ch->connect3 = outd; |
| break; | break; |
| Line 380 void opngen_reset(void) { | Line 381 void opngen_reset(void) { |
| OPNSLOT *slot; | OPNSLOT *slot; |
| UINT j; | UINT j; |
| ZeroMemory(&opngen, sizeof(opngen)); | |
| ZeroMemory(opnch, sizeof(opnch)); | ZeroMemory(opnch, sizeof(opnch)); |
| ZeroMemory(fm_keyreg, sizeof(fm_keyreg)); | opngen.playchannels = 3; |
| playchannels = 3; | |
| ch = opnch; | ch = opnch; |
| for (i=0; i<OPNCH_MAX; i++) { | for (i=0; i<OPNCH_MAX; i++) { |
| Line 415 void opngen_setcfg(BYTE maxch, UINT flag | Line 416 void opngen_setcfg(BYTE maxch, UINT flag |
| OPNCH *ch; | OPNCH *ch; |
| UINT i; | UINT i; |
| playchannels = maxch; | opngen.playchannels = maxch; |
| ch = opnch; | ch = opnch; |
| if ((flag & OPN_CHMASK) == OPN_STEREO) { | if ((flag & OPN_CHMASK) == OPN_STEREO) { |
| for (i=0; i<OPNCH_MAX; i++) { | for (i=0; i<OPNCH_MAX; i++) { |
| Line 502 void opngen_setreg(BYTE chbase, BYTE reg | Line 503 void opngen_setreg(BYTE chbase, BYTE reg |
| fn = ((ch->keyfunc[0] & 7) << 8) + value; | fn = ((ch->keyfunc[0] & 7) << 8) + value; |
| ch->kcode[0] = (blk << 2) | kftable[fn >> 7]; | ch->kcode[0] = (blk << 2) | kftable[fn >> 7]; |
| // ch->keynote[0] = fn * opmbaserate / (1L << (22-blk)); | // ch->keynote[0] = fn * opmbaserate / (1L << (22-blk)); |
| ch->keynote[0] = (fn << (baseratebit + blk)) >> 6; | ch->keynote[0] = (fn << (opncfg.ratebit + blk)) >> 6; |
| channleupdate(ch); | channleupdate(ch); |
| break; | break; |
| Line 516 void opngen_setreg(BYTE chbase, BYTE reg | Line 517 void opngen_setreg(BYTE chbase, BYTE reg |
| fn = ((ch->keyfunc[chpos+1] & 7) << 8) + value; | fn = ((ch->keyfunc[chpos+1] & 7) << 8) + value; |
| ch->kcode[chpos+1] = (blk << 2) | kftable[fn >> 7]; | ch->kcode[chpos+1] = (blk << 2) | kftable[fn >> 7]; |
| // ch->keynote[chpos+1] = fn * opmbaserate / (1L << (22-blk)); | // ch->keynote[chpos+1] = fn * opmbaserate / (1L << (22-blk)); |
| ch->keynote[chpos+1] = (fn << (baseratebit + blk)) >> 6; | ch->keynote[chpos+1] = (fn << (opncfg.ratebit + blk)) >> 6; |
| channleupdate(ch); | channleupdate(ch); |
| break; | break; |
| Line 553 void opngen_keyon(UINT chnum, BYTE value | Line 554 void opngen_keyon(UINT chnum, BYTE value |
| UINT i; | UINT i; |
| sound_sync(); | sound_sync(); |
| fm_keyreg[chnum] = value; | opngen.keyreg[chnum] = value; |
| opngen.playing++; | |
| ch = opnch + chnum; | ch = opnch + chnum; |
| ch->playing |= value >> 4; | |
| slot = ch->slot; | slot = ch->slot; |
| bit = 0x10; | bit = 0x10; |
| for (i=0; i<4; i++) { | for (i=0; i<4; i++) { |