示例#1
0
 static void TimerAOver(FM_ST ST)
 {
     /* status set if enabled */
     if ((ST.mode & 0x04) != 0) FM_STATUS_SET(ST, 0x01);
     /* clear or reload the counter */
     if (ST.timermodel == FM_TIMER_INTERVAL)
     {
         ST.TAC = (1024 - ST.TA);
         if (ST.Timer_Handler != null) ST.Timer_Handler(ST.index, 0, (int)ST.TAC, ST.TimerBase);
     }
     else ST.TAC = 0;
 }
示例#2
0
 /* Timer B Overflow */
 static void TimerBOver(FM_ST ST)
 {
     /* status set if enabled */
     if ((ST.mode & 0x08) != 0) FM_STATUS_SET(ST, 0x02);
     /* clear or reload the counter */
     if (ST.timermodel == FM_TIMER_INTERVAL)
     {
         ST.TBC = (256 - ST.TB) << 4;
         if (ST.Timer_Handler != null) ST.Timer_Handler(ST.index, 1, (int)ST.TBC, ST.TimerBase);
     }
     else ST.TBC = 0;
 }
示例#3
0
        static void init_timetables(FM_ST ST, byte[] DTTABLE, int ARRATE, int DRRATE)
        {
            int i, d;
            double rate;

            /* DeTune table */
            for (d = 0; d <= 3; d++)
            {
                for (i = 0; i <= 31; i++)
                {
                    rate = (double)DTTABLE[d * 32 + i] * ST.freqbase * FREQ_RATE;
                    ST.DT_TABLE[d][i] = (int)rate;
                    ST.DT_TABLE[d + 4][i] = (int)-rate;
                }
            }
            /* make Attack & Decay tables */
            for (i = 0; i < 4; i++) ST.AR_TABLE[i] = ST.DR_TABLE[i] = 0;
            for (i = 4; i < 64; i++)
            {
                rate = ST.freqbase;						/* frequency rate */
                if (i < 60) rate *= 1.0 + (i & 3) * 0.25;		/* b0-1 : x1 , x1.25 , x1.5 , x1.75 */
                rate *= 1 << ((i >> 2) - 1);						/* b2-5 : shift bit */
                rate *= (double)(EG_ENT << ENV_BITS);
                ST.AR_TABLE[i] = (int)(rate / ARRATE);
                ST.DR_TABLE[i] = (int)(rate / DRRATE);
            }
            ST.AR_TABLE[62] = EG_AED - 1;
            ST.AR_TABLE[63] = EG_AED - 1;
            for (i = 64; i < 94; i++)
            {	/* make for overflow area */
                ST.AR_TABLE[i] = ST.AR_TABLE[63];
                ST.DR_TABLE[i] = ST.DR_TABLE[63];
            }

#if false
	for (i = 0;i < 64 ;i++){
		Log(LOG_WAR,"rate %2d , ar %f ms , dr %f ms \n",i,
			((double)(EG_ENT<<ENV_BITS) / ST.AR_TABLE[i]) * (1000.0 / ST.rate),
			((double)(EG_ENT<<ENV_BITS) / ST.DR_TABLE[i]) * (1000.0 / ST.rate) );
	}
#endif
        }
示例#4
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;
                }
            }
        }
示例#5
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);
 }
示例#6
0
        static void FMSetMode(FM_ST ST, int n, int v)
        {
            /* b7 = CSM MODE */
            /* b6 = 3 slot mode */
            /* b5 = reset b */
            /* b4 = reset a */
            /* b3 = timer enable b */
            /* b2 = timer enable a */
            /* b1 = load b */
            /* b0 = load a */
            ST.mode = (uint)v;

            /* reset Timer b flag */
            if ((v & 0x20) != 0)
                FM_STATUS_RESET(ST, 0x02);
            /* reset Timer a flag */
            if ((v & 0x10) != 0)
                FM_STATUS_RESET(ST, 0x01);
            /* load b */
            if ((v & 0x02) != 0)
            {
                if (ST.TBC == 0)
                {
                    ST.TBC = (256 - ST.TB) << 4;
                    /* External timer handler */
                    if (ST.Timer_Handler != null) ST.Timer_Handler(n, 1, (int)ST.TBC, ST.TimerBase);
                }
            }
            else if (ST.timermodel == FM_TIMER_INTERVAL)
            {	/* stop interbval timer */
                if (ST.TBC != 0)
                {
                    ST.TBC = 0;
                    if (ST.Timer_Handler != null) ST.Timer_Handler(n, 1, 0, ST.TimerBase);
                }
            }
            /* load a */
            if ((v & 0x01) != 0)
            {
                if (ST.TAC == 0)
                {
                    ST.TAC = (1024 - ST.TA);
                    /* External timer handler */
                    if (ST.Timer_Handler != null) ST.Timer_Handler(n, 0, (int)ST.TAC, ST.TimerBase);
                }
            }
            else if (ST.timermodel == FM_TIMER_INTERVAL)
            {	/* stop interbval timer */
                if (ST.TAC != 0)
                {
                    ST.TAC = 0;
                    if (ST.Timer_Handler != null) ST.Timer_Handler(n, 0, 0, ST.TimerBase);
                }
            }
        }
示例#7
0
 static void FM_STATUS_RESET(FM_ST ST, int flag)
 {
     /* reset status flag */
     ST.status &= (byte)~flag;
     if ((ST.irq) != 0 && (ST.status & ST.irqmask) == 0)
     {
         ST.irq = 0;
         /* callback user interrupt handler (IRQ is ON to OFF) */
         if (ST.IRQ_Handler != null) ST.IRQ_Handler(ST.index, 0);
     }
 }
示例#8
0
 static void FM_IRQMASK_SET(FM_ST ST, int flag)
 {
     ST.irqmask = (byte)flag;
     /* IRQ handling check */
     FM_STATUS_SET(ST, 0);
     FM_STATUS_RESET(ST, 0);
 }
示例#9
0
 static void FM_STATUS_SET(FM_ST ST, int flag)
 {
     /* set status flag */
     ST.status |= (byte)flag;
     if ((ST.irq) == 0 && (ST.status & ST.irqmask) != 0)
     {
         ST.irq = 1;
         /* callback user interrupt handler (IRQ is OFF to ON) */
         if (ST.IRQ_Handler != null) ST.IRQ_Handler(ST.index, 1);
     }
 }
示例#10
0
        public static void YM2203UpdateOne(int num, _ShortPtr buffer, int length)
        {
            YM2203 F2203 = (FM2203[num]);
            FM_OPN OPN = (FM2203[num].OPN);
            int i;
            FM_CH ch;
            _ShortPtr buf = new _ShortPtr(buffer);

            cur_chip = F2203;
            State = F2203.OPN.ST;
            cch[0] = F2203.CH[0];
            cch[1] = F2203.CH[1];
            cch[2] = F2203.CH[2];
#if FM_LFO_SUPPORT
            /* LFO */
            lfo_amd = 0;
            lfo_pmd = 0;
#endif
            /* frequency counter channel A */
            CALC_FCOUNT(cch[0]);
            /* frequency counter channel B */
            CALC_FCOUNT(cch[1]);
            /* frequency counter channel C */
            if ((State.mode & 0xc0) != 0)
            {
                /* 3SLOT MODE */
                if (cch[2].SLOT[SLOT1].Incr == unchecked((uint)-1))
                {
                    /* 3 slot mode */
                    CALC_FCSLOT(cch[2].SLOT[SLOT1], (int)OPN.SL3.fc[1], OPN.SL3.kcode[1]);
                    CALC_FCSLOT(cch[2].SLOT[SLOT2], (int)OPN.SL3.fc[2], OPN.SL3.kcode[2]);
                    CALC_FCSLOT(cch[2].SLOT[SLOT3], (int)OPN.SL3.fc[0], OPN.SL3.kcode[0]);
                    CALC_FCSLOT(cch[2].SLOT[SLOT4], (int)cch[2].fc, cch[2].kcode);
                }
            }
            else CALC_FCOUNT(cch[2]);

            for (i = 0; i < length; i++)
            {
                /*            channel A         channel B         channel C      */
                out_ch[OUTD_CENTER] = 0;
                /* calcrate FM */
                //for( ch=cch[0] ; ch <= cch[2] ; ch++)
                for (int kk = 0; kk < 2; kk++)

                    FM_CALC_CH(cch[kk]);
                /* limit check */
                Limit(ref out_ch[OUTD_CENTER], FM_MAXOUT, FM_MINOUT);
                /* store to sound buffer */
                buf.write16(i, (ushort)(out_ch[OUTD_CENTER] >> FM_OUTSB));
                /* timer controll */
                INTERNAL_TIMER_A(State, cch[2]);
            }
            INTERNAL_TIMER_B(State, length);
        }
示例#11
0
 static void INTERNAL_TIMER_B(FM_ST ST, int step) { }
示例#12
0
 /* external timer mode */
 static void INTERNAL_TIMER_A(FM_ST ST, FM_CH CSM_CH) { }
示例#13
0
        public static void OPMUpdateOne(int num, _ShortPtr[] buffer, int length)
        {
            YM2151 OPM = (FMOPM[num]);
            int i;
            int amd, pmd;
            FM_CH ch;
            _ShortPtr bufL, bufR;

            /* set bufer */
            bufL = buffer[0];
            bufR = buffer[1];

            if ((object)OPM != cur_chip)
            {
                cur_chip = OPM;

                State = OPM.ST;
                /* channel pointer */
                cch[0] = OPM.CH[0];
                cch[1] = OPM.CH[1];
                cch[2] = OPM.CH[2];
                cch[3] = OPM.CH[3];
                cch[4] = OPM.CH[4];
                cch[5] = OPM.CH[5];
                cch[6] = OPM.CH[6];
                cch[7] = OPM.CH[7];
                /* ch7.op4 noise mode / step */
                NoiseIncr = OPM.NoiseIncr;
                NoiseCnt = OPM.NoiseCnt;
#if FM_LFO_SUPPORT
                /* LFO */
                LFOCnt = OPM.LFOCnt;
                //LFOIncr = OPM.LFOIncr;
                if (LFOIncr == 0) { lfo_amd = 0; lfo_pmd = 0; }
                LFO_wave = OPM.wavetype;
#endif
            }
            amd = OPM.amd;
            pmd = OPM.pmd;
            if (amd == 0 && pmd == 0)
                LFOIncr = 0;
            else
                LFOIncr = OPM.LFOIncr;

            OPM_CALC_FCOUNT(OPM, cch[0]);
            OPM_CALC_FCOUNT(OPM, cch[1]);
            OPM_CALC_FCOUNT(OPM, cch[2]);
            OPM_CALC_FCOUNT(OPM, cch[3]);
            OPM_CALC_FCOUNT(OPM, cch[4]);
            OPM_CALC_FCOUNT(OPM, cch[5]);
            OPM_CALC_FCOUNT(OPM, cch[6]);
            /* CSM check */
            OPM_CALC_FCOUNT(OPM, cch[7]);

            for (i = 0; i < length; i++)
            {
#if FM_LFO_SUPPORT
                /* LFO */
                if (LFOIncr != 0)
                {
                    int depth = LFO_wave[(int)((LFOCnt += LFOIncr) >> LFO_SHIFT)];
                    lfo_amd = (uint)(depth * amd);
                    lfo_pmd = (depth - (LFO_RATE / 127 / 2)) * pmd;
                }
#endif
                /* clear output acc. */
                out_ch[OUTD_LEFT] = out_ch[OUTD_RIGHT] = out_ch[OUTD_CENTER] = 0;
                /* calcrate channel output */
                //for(ch = cch[0] ; ch <= cch[6] ; ch++)
                for (int k = 0; k < 6; k++)
                {
                    ch = cch[k];
                    FM_CALC_CH(ch);
                    OPM_CALC_CH7(cch[7]);
                    /* buffering */
                    //FM_BUFFERING_STEREO;
#if FM_STEREO_MIX
/* stereo mixing */
{														
	/* get left & right output with clipping */			
	out_ch[OUTD_LEFT]  += out_ch[OUTD_CENTER];				
	Limit( out_ch[OUTD_LEFT] , FM_MAXOUT, FM_MINOUT );	
	out_ch[OUTD_RIGHT] += out_ch[OUTD_CENTER];				
	Limit( out_ch[OUTD_RIGHT], FM_MAXOUT, FM_MINOUT );	
	/* buffering */										
	((FMSAMPLE_MIX *)bufL)[i] = ((out_ch[OUTD_LEFT]>>FM_OUTSB)<<FM_OUTPUT_BIT)|(out_ch[OUTD_RIGHT]>>FM_OUTSB); 
}
#else
                    /* stereo separate */
                    {
                        /* get left & right output with clipping */
                        out_ch[OUTD_LEFT] += out_ch[OUTD_CENTER];
                        Limit(ref  out_ch[OUTD_LEFT], FM_MAXOUT, FM_MINOUT);
                        out_ch[OUTD_RIGHT] += out_ch[OUTD_CENTER];
                        Limit(ref  out_ch[OUTD_RIGHT], FM_MAXOUT, FM_MINOUT);
                        /* buffering */
                        bufL.write16(i, (ushort)(out_ch[OUTD_LEFT] >> FM_OUTSB));
                        bufR.write16(i, (ushort)(out_ch[OUTD_RIGHT] >> FM_OUTSB));
                    }
#endif
                    /* timer A controll */
                    INTERNAL_TIMER_A(State, cch[7]);
                }
                INTERNAL_TIMER_B(State, length);
                OPM.NoiseCnt = NoiseCnt;
#if FM_LFO_SUPPORT
                OPM.LFOCnt = LFOCnt;
#endif
            }

        }