public static void YM3812UpdateOne(FM_OPL OPL, _ShortPtr buffer, int length) { int i; int data; _ShortPtr buf = buffer; uint amsCnt = (uint)OPL.amsCnt; uint vibCnt = (uint)OPL.vibCnt; byte rythm = (byte)(OPL.rythm & 0x20); OPL_CH CH; int R_CH; if ((object)OPL != cur_chip) { cur_chip = OPL; /* channel pointers */ S_CH = OPL.P_CH; E_CH = 9;// S_CH[9]; /* rythm slot */ SLOT7_1 = S_CH[7].SLOT[SLOT1]; SLOT7_2 = S_CH[7].SLOT[SLOT2]; SLOT8_1 = S_CH[8].SLOT[SLOT1]; SLOT8_2 = S_CH[8].SLOT[SLOT2]; /* LFO state */ amsIncr = OPL.amsIncr; vibIncr = OPL.vibIncr; ams_table = OPL.ams_table; vib_table = OPL.vib_table; } R_CH = rythm != 0 ? 6 : E_CH; for (i = 0; i < length; i++) { /* channel A channel B channel C */ /* LFO */ ams = ams_table[(int)((amsCnt += (uint)amsIncr) >> AMS_SHIFT)]; vib = vib_table[(int)((vibCnt += (uint)vibIncr) >> VIB_SHIFT)]; outd[0] = 0; /* FM part */ for (int k = 0; k != R_CH; k++) { CH = S_CH[k]; //for(CH=S_CH ; CH < R_CH ; CH++) OPL_CALC_CH(CH); } /* Rythn part */ if (rythm != 0) OPL_CALC_RH(S_CH); /* limit check */ data = Limit(outd[0], OPL_MAXOUT, OPL_MINOUT); /* store to sound buffer */ buf.write16(i, (ushort)(data >> OPL_OUTSB)); } OPL.amsCnt = (int)amsCnt; OPL.vibCnt = (int)vibCnt; }
static void OPL_KEYOFF(OPL_SLOT SLOT) { if (SLOT.evm > ENV_MOD_RR) { /* set envelope counter from envleope output */ SLOT.evm = ENV_MOD_RR; if ((SLOT.evc & EG_DST) == 0) //SLOT.evc = (ENV_CURVE[SLOT.evc>>ENV_BITS]<<ENV_BITS) + EG_DST; SLOT.evc = EG_DST; SLOT.eve = EG_DED; SLOT.evs = SLOT.evsr; } }
public OPL_CH() { SLOT[0] = new OPL_SLOT(); SLOT[1] = new OPL_SLOT(); }
static void OPL_KEYON(OPL_SLOT SLOT) { /* sin wave restart */ SLOT.Cnt = 0; /* set attack */ SLOT.evm = ENV_MOD_AR; SLOT.evs = SLOT.evsa; SLOT.evc = EG_AST; SLOT.eve = EG_AED; }
static void CALC_FCSLOT(OPL_CH CH, OPL_SLOT SLOT) { int ksr; /* frequency step counter */ SLOT.Incr = CH.fc * SLOT.mul; ksr = CH.kcode >> SLOT.KSR; if (SLOT.ksr != ksr) { SLOT.ksr = (byte)ksr; /* attack , decay rate recalcration */ SLOT.evsa = SLOT.AR[ksr]; SLOT.evsd = SLOT.DR[ksr]; SLOT.evsr = SLOT.RR[ksr]; } SLOT.TLL = (int)(SLOT.TL + (CH.ksl_base >> SLOT.ksl)); }
static uint OPL_CALC_SLOT(OPL_SLOT SLOT) { /* calcrate envelope generator */ if ((SLOT.evc += SLOT.evs) >= SLOT.eve) { switch (SLOT.evm) { case ENV_MOD_AR: /* ATTACK . DECAY1 */ /* next DR */ SLOT.evm = ENV_MOD_DR; SLOT.evc = EG_DST; SLOT.eve = SLOT.SL; SLOT.evs = SLOT.evsd; break; case ENV_MOD_DR: /* DECAY . SL or RR */ SLOT.evc = SLOT.SL; SLOT.eve = EG_DED; if (SLOT.eg_typ != 0) { SLOT.evs = 0; } else { SLOT.evm = ENV_MOD_RR; SLOT.evs = SLOT.evsr; } break; case ENV_MOD_RR: /* RR . OFF */ SLOT.evc = EG_OFF; SLOT.eve = EG_OFF + 1; SLOT.evs = 0; break; } } /* calcrate envelope */ return (uint)(SLOT.TLL + ENV_CURVE[SLOT.evc >> ENV_BITS] + (SLOT.ams != 0 ? ams : 0)); }
static int OP_OUT(OPL_SLOT slot, int env, int con) { return slot.wavetable[((slot.Cnt + con) / (0x1000000 / SIN_ENT)) & (SIN_ENT - 1)][env]; }
static int OP_OUT(OPL_SLOT slot, uint env, int con) { return ((IntSubArray[])slot.wavetable)[((slot.Cnt + con) / (0x1000000 / SIN_ENT)) & (SIN_ENT - 1)][(int)env]; }