示例#1
0
        static void reset_channel(FM_ST ST, FM_CH[] CH, int chan)
        {
            int c, s;

            ST.mode = 0;	/* normal mode */
            FM_STATUS_RESET(ST, 0xff);
            ST.TA = 0;
            ST.TAC = 0;
            ST.TB = 0;
            ST.TBC = 0;

            for (c = 0; c < chan; c++)
            {
                CH[c] = new FM_CH();
                CH[c].fc = 0;
                CH[c].PAN = OUTD_CENTER;
                for (s = 0; s < 4; s++)
                {
                    CH[c].SLOT[s].SEG = 0;
                    CH[c].SLOT[s].eg_next = FM_EG_Release;
                    CH[c].SLOT[s].evc = EG_OFF;
                    CH[c].SLOT[s].eve = EG_OFF + 1;
                    CH[c].SLOT[s].evs = 0;
                }
            }
        }
示例#2
0
 /* CSM Key Controll */
 static void CSMKeyControll(FM_CH CH)
 {
     /* int ksl = KSL[CH.kcode]; */
     /* all key off */
     FM_KEYOFF(CH, SLOT1);
     FM_KEYOFF(CH, SLOT2);
     FM_KEYOFF(CH, SLOT3);
     FM_KEYOFF(CH, SLOT4);
     /* total level latch */
     CH.SLOT[SLOT1].TLL = CH.SLOT[SLOT1].TL /*+ ksl*/;
     CH.SLOT[SLOT2].TLL = CH.SLOT[SLOT2].TL /*+ ksl*/;
     CH.SLOT[SLOT3].TLL = CH.SLOT[SLOT3].TL /*+ ksl*/;
     CH.SLOT[SLOT4].TLL = CH.SLOT[SLOT4].TL /*+ ksl*/;
     /* all key on */
     FM_KEYON(CH, SLOT1);
     FM_KEYON(CH, SLOT2);
     FM_KEYON(CH, SLOT3);
     FM_KEYON(CH, SLOT4);
 }
示例#3
0
 /* set total level */
 static void set_tl(FM_CH CH, FM_SLOT SLOT, int v, int csmflag)
 {
     v &= 0x7f;
     v = (v << 7) | v; /* 7bit . 14bit */
     SLOT.TL = (v * EG_ENT) >> 14;
     if (csmflag == 0)
     {	/* not CSM latch total level */
         SLOT.TLL = SLOT.TL /* + KSL[CH.kcode] */;
     }
 }
示例#4
0
 /* set attack rate & key scale  */
 static void set_ar_ksr(FM_CH CH, FM_SLOT SLOT, int v, IntSubArray ar_table)
 {
     SLOT.KSR = (byte)(3 - (v >> 6));
     SLOT.AR = (v &= 0x1f) != 0 ? new IntSubArray(ar_table, v << 1) : new IntSubArray(RATE_0);
     SLOT.evsa = SLOT.AR[SLOT.ksr];
     if (SLOT.eg_next == FM_EG_AR) SLOT.evs = SLOT.evsa;
     CH.SLOT[SLOT1].Incr = unchecked((uint)-1);
 }
示例#5
0
        static void setup_connection(FM_CH CH)
        {
            IntSubArray carrier = new IntSubArray(out_ch,CH.PAN); /* NONE,LEFT,RIGHT or CENTER */

            switch (CH.ALGO)
            {
                case 0:
                    /*  PG---S1---S2---S3---S4---OUT */
                    CH.connect1 = new IntSubArray(pg_in2);
                    CH.connect2 = new IntSubArray(pg_in3);
                    CH.connect3 = new IntSubArray(pg_in4);
                    break;
                case 1:
                    /*  PG---S1-+-S3---S4---OUT */
                    /*  PG---S2-+               */
                    CH.connect1 = new IntSubArray(pg_in3);
                    CH.connect2 = new IntSubArray(pg_in3);
                    CH.connect3 = new IntSubArray(pg_in4);
                    break;
                case 2:
                    /* PG---S1------+-S4---OUT */
                    /* PG---S2---S3-+          */
                    CH.connect1 = new IntSubArray(pg_in4);
                    CH.connect2 = new IntSubArray(pg_in3);
                    CH.connect3 = new IntSubArray(pg_in4);
                    break;
                case 3:
                    /* PG---S1---S2-+-S4---OUT */
                    /* PG---S3------+          */
                    CH.connect1 = new IntSubArray(pg_in2);
                    CH.connect2 = new IntSubArray(pg_in4);
                    CH.connect3 = new IntSubArray(pg_in4);
                    break;
                case 4:
                    /* PG---S1---S2-+--OUT */
                    /* PG---S3---S4-+      */
                    CH.connect1 = new IntSubArray(pg_in2);
                    CH.connect2 = new IntSubArray(carrier);
                    CH.connect3 = new IntSubArray(pg_in4);
                    break;
                case 5:
                    /*         +-S2-+     */
                    /* PG---S1-+-S3-+-OUT */
                    /*         +-S4-+     */
                    CH.connect1 = null;	/* special case */
                    CH.connect2 = new IntSubArray(carrier);
                    CH.connect3 = new IntSubArray(carrier);
                    break;
                case 6:
                    /* PG---S1---S2-+     */
                    /* PG--------S3-+-OUT */
                    /* PG--------S4-+     */
                    CH.connect1 = new IntSubArray(pg_in2);
                    CH.connect2 = new IntSubArray(carrier);
                    CH.connect3 = new IntSubArray(carrier);
                    break;
                case 7:
                    /* PG---S1-+     */
                    /* PG---S2-+-OUT */
                    /* PG---S3-+     */
                    /* PG---S4-+     */
                    CH.connect1 = new IntSubArray(carrier);
                    CH.connect2 = new IntSubArray(carrier);
                    CH.connect3 = new IntSubArray(carrier);
                    break;
            }
            CH.connect4 = carrier;
        }
示例#6
0
 /* set detune & multiple */
 static void set_det_mul(FM_ST ST, FM_CH CH, FM_SLOT SLOT, int v)
 {
     SLOT.mul = (uint)MUL_TABLE[v & 0x0f];
     SLOT.DT = ST.DT_TABLE[(v >> 4) & 7];
     CH.SLOT[SLOT1].Incr = unchecked((uint)-1);
 }
示例#7
0
        static void FM_KEYON(FM_CH CH, int s)
        {
            FM_SLOT SLOT = CH.SLOT[s];
            if (!FM_KEY_IS(SLOT))
            {
                /* restart Phage Generator */
                SLOT.Cnt = 0;
                /* phase . Attack */
#if FM_SEG_SUPPORT
		if( SLOT.SEG&8 ) SLOT.eg_next = FM_EG_SSG_AR;
		else
#endif
                SLOT.eg_next = FM_EG_AR;
                SLOT.evs = SLOT.evsa;
#if false
		/* convert decay count to attack count */
		/* --- This caused the problem by credit sound of paper boy. --- */
		SLOT.evc = EG_AST + DRAR_TABLE[ENV_CURVE[SLOT.evc>>ENV_BITS]];/* + SLOT.evs;*/
#else
                /* reset attack counter */
                SLOT.evc = EG_AST;
#endif
                SLOT.eve = EG_AED;
            }
        }
示例#8
0
 /* ----- key off of SLOT ----- */
 static void FM_KEYOFF(FM_CH CH, int s)
 {
     FM_SLOT SLOT = CH.SLOT[s];
     if (FM_KEY_IS(SLOT))
     {
         /* if Attack phase then adjust envelope counter */
         if (SLOT.evc < EG_DST)
             SLOT.evc = (ENV_CURVE[SLOT.evc >> ENV_BITS] << ENV_BITS) + EG_DST;
         /* phase . Release */
         SLOT.eg_next = FM_EG_Release;
         SLOT.eve = EG_DED;
         SLOT.evs = SLOT.evsr;
     }
 }
示例#9
0
 static void CALC_FCOUNT(FM_CH CH)
 {
     if (CH.SLOT[SLOT1].Incr == unchecked((uint)-1))
     {
         int fc = (int)CH.fc;
         int kc = CH.kcode;
         CALC_FCSLOT(CH.SLOT[SLOT1], fc, kc);
         CALC_FCSLOT(CH.SLOT[SLOT2], fc, kc);
         CALC_FCSLOT(CH.SLOT[SLOT3], fc, kc);
         CALC_FCSLOT(CH.SLOT[SLOT4], fc, kc);
     }
 }
示例#10
0
 public YM2203()
 {
     for (int i = 0; i < 3; i++)
         CH[i] = new FM_CH();
 }
示例#11
0
 /* external timer mode */
 static void INTERNAL_TIMER_A(FM_ST ST, FM_CH CSM_CH) { }
示例#12
0
        static void FM_CALC_CH(FM_CH CH)
        {
            uint eg_out1 = 0, eg_out2 = 0, eg_out3 = 0, eg_out4 = 0;  //envelope output

            /* Phase Generator */
#if FM_LFO_SUPPORT
            int pms = lfo_pmd * CH.pms / LFO_RATE;
            if (pms != 0)
            {
                pg_in1[0] = (int)((CH.SLOT[SLOT1].Cnt += (uint)(CH.SLOT[SLOT1].Incr + (int)(pms * CH.SLOT[SLOT1].Incr) / PMS_RATE)));
                pg_in2[0] = (int)((CH.SLOT[SLOT2].Cnt += (uint)(CH.SLOT[SLOT2].Incr + (int)(pms * CH.SLOT[SLOT2].Incr) / PMS_RATE)));
                pg_in3[0] = (int)((CH.SLOT[SLOT3].Cnt += (uint)(CH.SLOT[SLOT3].Incr + (int)(pms * CH.SLOT[SLOT3].Incr) / PMS_RATE)));
                pg_in4[0] = (int)((CH.SLOT[SLOT4].Cnt += (uint)(CH.SLOT[SLOT4].Incr + (int)(pms * CH.SLOT[SLOT4].Incr) / PMS_RATE)));
            }
            else
#endif
            {
                pg_in1[0] = (int)((CH.SLOT[SLOT1].Cnt += CH.SLOT[SLOT1].Incr));
                pg_in2[0] = (int)((CH.SLOT[SLOT2].Cnt += CH.SLOT[SLOT2].Incr));
                pg_in3[0] = (int)((CH.SLOT[SLOT3].Cnt += CH.SLOT[SLOT3].Incr));
                pg_in4[0] = (int)((CH.SLOT[SLOT4].Cnt += CH.SLOT[SLOT4].Incr));
            }

            /* Envelope Generator */
            FM_CALC_EG(ref eg_out1, CH.SLOT[SLOT1]);
            FM_CALC_EG(ref eg_out2, CH.SLOT[SLOT2]);
            FM_CALC_EG(ref eg_out3, CH.SLOT[SLOT3]);
            FM_CALC_EG(ref eg_out4, CH.SLOT[SLOT4]);

            /* Connection */
            if (eg_out1 < EG_CUT_OFF)	/* SLOT 1 */
            {
                if (CH.FB != 0)
                {
                    /* with self feed back */
                    pg_in1[0] += (CH.op1_out[0] + CH.op1_out[1]) >> CH.FB;
                    CH.op1_out[1] = CH.op1_out[0];
                }
                CH.op1_out[0] = OP_OUT(pg_in1[0], eg_out1);
                /* output slot1 */
                if (CH.connect1 == null)
                {
                    /* algorythm 5  */
                    pg_in2[0] += CH.op1_out[0];
                    pg_in3[0] += CH.op1_out[0];
                    pg_in4[0] += CH.op1_out[0];
                }
                else
                {
                    /* other algorythm */
                    CH.connect1[0] += CH.op1_out[0];
                }
            }
            if (eg_out2 < EG_CUT_OFF)	/* SLOT 2 */
                CH.connect2[0] += OP_OUT(pg_in2[0], eg_out2);
            if (eg_out3 < EG_CUT_OFF)	/* SLOT 3 */
                CH.connect3[0] += OP_OUT(pg_in3[0], eg_out3);
            if (eg_out4 < EG_CUT_OFF)	/* SLOT 4 */
                CH.connect4[0] += OP_OUT(pg_in4[0], eg_out4);
        }
示例#13
0
        static void OPM_CALC_FCOUNT(YM2151 OPM, FM_CH CH)
        {
            if (CH.SLOT[SLOT1].Incr == unchecked((uint)-1))
            {
                int fc = (int)CH.fc;
                int kc = CH.kcode;

                CALC_FCSLOT(CH.SLOT[SLOT1], (int)(OPM.KC_TABLE[fc + CH.SLOT[SLOT1].DT2]), kc);
                CALC_FCSLOT(CH.SLOT[SLOT2], (int)(OPM.KC_TABLE[fc + CH.SLOT[SLOT2].DT2]), kc);
                CALC_FCSLOT(CH.SLOT[SLOT3], (int)(OPM.KC_TABLE[fc + CH.SLOT[SLOT3].DT2]), kc);
                CALC_FCSLOT(CH.SLOT[SLOT4], (int)(OPM.KC_TABLE[fc + CH.SLOT[SLOT4].DT2]), kc);
            }
        }