NScumm.Core.FmOPL.OPL_CALC_RH C# (CSharp) Method

OPL_CALC_RH() private method

private OPL_CALC_RH ( OPL_CH CH ) : void
CH OPL_CH
return void
        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;
        }