void OPL_CALC_RH(OPL_CH CH)
{
uint env_tam, env_sd, env_top, env_hh;
// This code used to do int(rnd.getRandomBit() * (WHITE_NOISE_db / EG_STEP)),
// but EG_STEP = 96.0/EG_ENT, and WHITE_NOISE_db=6.0. So, that's equivalent to
// int(rnd.getRandomBit() * EG_ENT/16). We know that EG_ENT is 4096, or 1024,
// or 128, so we can safely avoid any FP ops.
int whitenoise = rnd.getRandomBit() * (EG_ENT >> 4);
int tone8;
OPL_SLOT* SLOT;
int env_out;
/* BD : same as FM serial mode and output level is large */
feedback2 = 0;
/* SLOT 1 */
SLOT = &CH[6].SLOT[SLOT1];
env_out = OPL_CALC_SLOT(SLOT);
if (env_out < EG_ENT - 1)
{
/* PG */
if (SLOT.vib)
SLOT.Cnt += (SLOT.Incr * vib) >> VIB_RATE_SHIFT;
else
SLOT.Cnt += SLOT.Incr;
/* connection */
if (CH[6].FB)
{
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 = CH[6].op1_out[0] = OP_OUT(SLOT, env_out, feedback1);
}
else
{
feedback2 = OP_OUT(SLOT, env_out, 0);
}
}
else
{
feedback2 = 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 = OPL_CALC_SLOT(SLOT);
if (env_out < EG_ENT - 1)
{
/* PG */
if (SLOT.vib)
SLOT.Cnt += (SLOT.Incr * vib) >> VIB_RATE_SHIFT;
else
SLOT.Cnt += SLOT.Incr;
/* connection */
outd[0] += OP_OUT(SLOT, env_out, feedback2) * 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 = OPL_CALC_SLOT(SLOT7_2) + whitenoise;
env_tam = OPL_CALC_SLOT(SLOT8_1);
env_top = OPL_CALC_SLOT(SLOT8_2);
env_hh = OPL_CALC_SLOT(SLOT7_1) + whitenoise;
/* PG */
if (SLOT7_1.vib)
SLOT7_1.Cnt += (SLOT7_1.Incr * vib) >> (VIB_RATE_SHIFT - 1);
else
SLOT7_1.Cnt += 2 * SLOT7_1.Incr;
if (SLOT7_2.vib)
SLOT7_2.Cnt += (CH[7].fc * vib) >> (VIB_RATE_SHIFT - 3);
else
SLOT7_2.Cnt += (CH[7].fc * 8);
if (SLOT8_1.vib)
SLOT8_1.Cnt += (SLOT8_1.Incr * vib) >> VIB_RATE_SHIFT;
else
SLOT8_1.Cnt += SLOT8_1.Incr;
if (SLOT8_2.vib)
SLOT8_2.Cnt += ((CH[8].fc * 3) * vib) >> (VIB_RATE_SHIFT - 4);
else
SLOT8_2.Cnt += (CH[8].fc * 48);
tone8 = OP_OUT(SLOT8_2, whitenoise, 0);
/* SD */
if (env_sd < (uint)(EG_ENT - 1))
outd[0] += OP_OUT(SLOT7_1, env_sd, 0) * 8;
/* TAM */
if (env_tam < (uint)(EG_ENT - 1))
outd[0] += OP_OUT(SLOT8_1, env_tam, 0) * 2;
/* TOP-CY */
if (env_top < (uint)(EG_ENT - 1))
outd[0] += OP_OUT(SLOT7_2, env_top, tone8) * 2;
/* HH */
if (env_hh < (uint)(EG_ENT - 1))
outd[0] += OP_OUT(SLOT7_2, env_hh, tone8) * 2;
}