static void set_algorythm(OPL_CH CH) { int[] carrier = outd; CH.connect1 = CH.CON != 0 ? carrier : feedback2; CH.connect2 = carrier; }
static void CSMKeyControll(OPL_CH CH) { OPL_SLOT slot1 = CH.SLOT[SLOT1]; OPL_SLOT slot2 = CH.SLOT[SLOT2]; /* all key off */ OPL_KEYOFF(slot1); OPL_KEYOFF(slot2); /* total level latch */ slot1.TLL = (int)(slot1.TL + (CH.ksl_base >> slot1.ksl)); slot1.TLL = (int)(slot1.TL + (CH.ksl_base >> slot1.ksl)); /* key on */ CH.op1_out[0] = CH.op1_out[1] = 0; OPL_KEYON(slot1); OPL_KEYON(slot2); }
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 void OPL_CALC_RH(OPL_CH[] CH) { uint env_tam, env_sd, env_top, env_hh; int whitenoise = (int)((Mame.rand() & 1) * (WHITE_NOISE_db / EG_STEP)); int tone8; OPL_SLOT SLOT; int env_out; /* BD : same as FM serial mode and output level is large */ feedback2[0] = 0; /* SLOT 1 */ SLOT = CH[6].SLOT[SLOT1]; env_out = (int)OPL_CALC_SLOT(SLOT); if (env_out < EG_ENT - 1) { /* PG */ if (SLOT.vib != 0) SLOT.Cnt += (uint)((SLOT.Incr * vib / VIB_RATE)); else SLOT.Cnt += SLOT.Incr; /* connectoion */ if (CH[6].FB != 0) { int feedback1 = (CH[6].op1_out[0] + CH[6].op1_out[1]) >> CH[6].FB; CH[6].op1_out[1] = CH[6].op1_out[0]; feedback2[0] = CH[6].op1_out[0] = OP_OUT(SLOT, env_out, feedback1); } else { feedback2[0] = OP_OUT(SLOT, env_out, 0); } } else { feedback2[0] = 0; CH[6].op1_out[1] = CH[6].op1_out[0]; CH[6].op1_out[0] = 0; } /* SLOT 2 */ SLOT = CH[6].SLOT[SLOT2]; env_out = (int)OPL_CALC_SLOT(SLOT); if (env_out < EG_ENT - 1) { /* PG */ if (SLOT.vib != 0) SLOT.Cnt += (uint)(SLOT.Incr * vib / VIB_RATE); else SLOT.Cnt += SLOT.Incr; /* connectoion */ outd[0] += OP_OUT(SLOT, env_out, feedback2[0]) * 2; } // SD (17) = mul14[fnum7] + white noise // TAM (15) = mul15[fnum8] // TOP (18) = fnum6(mul18[fnum8]+whitenoise) // HH (14) = fnum7(mul18[fnum8]+whitenoise) + white noise env_sd = (uint)(OPL_CALC_SLOT(SLOT7_2) + whitenoise); env_tam = OPL_CALC_SLOT(SLOT8_1); env_top = OPL_CALC_SLOT(SLOT8_2); env_hh = (uint)(OPL_CALC_SLOT(SLOT7_1) + whitenoise); /* PG */ if (SLOT7_1.vib != 0) SLOT7_1.Cnt += (uint)(2 * SLOT7_1.Incr * vib / VIB_RATE); else SLOT7_1.Cnt += 2 * SLOT7_1.Incr; if (SLOT7_2.vib != 0) SLOT7_2.Cnt += (uint)((CH[7].fc * 8) * vib / VIB_RATE); else SLOT7_2.Cnt += (CH[7].fc * 8); if (SLOT8_1.vib != 0) SLOT8_1.Cnt += (uint)(SLOT8_1.Incr * vib / VIB_RATE); else SLOT8_1.Cnt += SLOT8_1.Incr; if (SLOT8_2.vib != 0) SLOT8_2.Cnt += (uint)((CH[8].fc * 48) * vib / VIB_RATE); else SLOT8_2.Cnt += (CH[8].fc * 48); tone8 = OP_OUT(SLOT8_2, whitenoise, 0); /* SD */ if (env_sd < EG_ENT - 1) outd[0] += OP_OUT(SLOT7_1, (int)env_sd, 0) * 8; /* TAM */ if (env_tam < EG_ENT - 1) outd[0] += OP_OUT(SLOT8_1, (int)env_tam, 0) * 2; /* TOP-CY */ if (env_top < EG_ENT - 1) outd[0] += OP_OUT(SLOT7_2, (int)env_top, tone8) * 2; /* HH */ if (env_hh < EG_ENT - 1) outd[0] += OP_OUT(SLOT7_2, (int)env_hh, tone8) * 2; }
static void OPL_CALC_CH(OPL_CH CH) { uint env_out; OPL_SLOT SLOT; feedback2[0] = 0; /* SLOT 1 */ SLOT = CH.SLOT[SLOT1]; env_out = OPL_CALC_SLOT(SLOT); if (env_out < EG_ENT - 1) { /* PG */ if (SLOT.vib != 0) SLOT.Cnt += (uint)(SLOT.Incr * vib / VIB_RATE); else SLOT.Cnt += SLOT.Incr; /* connectoion */ if (CH.FB != 0) { int feedback1 = (CH.op1_out[0] + CH.op1_out[1]) >> CH.FB; CH.op1_out[1] = CH.op1_out[0]; CH.connect1[0] += CH.op1_out[0] = OP_OUT(SLOT, (int)env_out, feedback1); } else { CH.connect1[0] += OP_OUT(SLOT, (int)env_out, 0); } } else { CH.op1_out[1] = CH.op1_out[0]; CH.op1_out[0] = 0; } /* SLOT 2 */ SLOT = CH.SLOT[SLOT2]; env_out = OPL_CALC_SLOT(SLOT); if (env_out < EG_ENT - 1) { /* PG */ if (SLOT.vib != 0) SLOT.Cnt += (uint)(SLOT.Incr * vib / VIB_RATE); else SLOT.Cnt += SLOT.Incr; /* connectoion */ outd[0] += OP_OUT(SLOT, (int)env_out, feedback2[0]); } }
static void set_algorythm(OPL_CH CH) { IntSubArray carrier = new IntSubArray(outd); CH.connect1 = CH.CON != 0 ? carrier : new IntSubArray(feedback2); CH.connect2 = carrier; }
public static void YM3812UpdateOne(FM_OPL OPL, _ShortPtr buffer, int length) { byte SLOT1 = 0, SLOT2 = 1; 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, R_CH; if (OPL != (object)opl_cur_chip) { opl_cur_chip = OPL; /* channel pointers */ S_CH = OPL.P_CH; E_CH = 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 ? S_CH[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 (i = 0, CH = S_CH[0]; i < S_CH.Length && CH != S_CH[i]; i++, CH = S_CH[i]) 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; }