Beispiel #1
0
 static void set_algorythm(OPL_CH CH)
 {
     int[] carrier = outd;
     CH.connect1 = CH.CON != 0 ? carrier : feedback2;
     CH.connect2 = carrier;
 }
Beispiel #2
0
 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);
 }
Beispiel #3
0
        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));
        }
Beispiel #4
0
        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;
        }
Beispiel #5
0
        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]);
            }
        }
Beispiel #6
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;
 }
Beispiel #7
0
        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;
        }