コード例 #1
0
ファイル: YM2413.cs プロジェクト: ddugovic/RASuite
		/* STEREO MODE (OPT) */
		void OPLL_set_pan(OPLL opll, uint ch, uint pan)
		{
			opll.pan[ch & 15] = pan & 3;
		}
コード例 #2
0
ファイル: YM2413.cs プロジェクト: ddugovic/RASuite
		void OPLL_copyPatch(OPLL opll, int num, OPLL_PATCH patch)
		{
			opll.patch[num] = (OPLL_PATCH)patch.Clone();
		}
コード例 #3
0
ファイル: YM2413.cs プロジェクト: ddugovic/RASuite
		/* Reset patch datas by system default. */
		void OPLL_reset_patch(OPLL opll, int type)
		{
			int i;

			for (i = 0; i < 19 * 2; i++)
				OPLL_copyPatch(opll, i, default_patch[type % OPLL_TONE_NUM, i]);
		}
コード例 #4
0
ファイル: YM2413.cs プロジェクト: ddugovic/RASuite
		/* Set F-Number ( fnum : 9bit ) */
		static void setFnumber(OPLL opll, int c, int fnum)
		{
			CAR(opll, c).fnum = fnum;
			MOD(opll, c).fnum = fnum;
		}
コード例 #5
0
ファイル: YM2413.cs プロジェクト: ddugovic/RASuite
		/* Change Rhythm Mode */
		static void update_rhythm_mode(OPLL opll)
		{
			if ((opll.patch_number[6] & 0x10) != 0)
			{
				if ((opll.slot_on_flag[SLOT_BD2] | (opll.reg[0x0e] & 32)) == 0)
				{
					opll.slot[SLOT_BD1].eg_mode = OPLL_EG_STATE.FINISH;
					opll.slot[SLOT_BD2].eg_mode = OPLL_EG_STATE.FINISH;
					setPatch(opll, 6, opll.reg[0x36] >> 4);
				}
			}
			else if ((opll.reg[0x0e] & 32) != 0)
			{
				opll.patch_number[6] = 16;
				opll.slot[SLOT_BD1].eg_mode = OPLL_EG_STATE.FINISH;
				opll.slot[SLOT_BD2].eg_mode = OPLL_EG_STATE.FINISH;
				setSlotPatch(opll.slot[SLOT_BD1], opll.patch[16 * 2 + 0]);
				setSlotPatch(opll.slot[SLOT_BD2], opll.patch[16 * 2 + 1]);
			}

			if ((opll.patch_number[7] & 0x10) != 0)
			{
				if (!((opll.slot_on_flag[SLOT_HH] != 0 && opll.slot_on_flag[SLOT_SD] != 0) | ((opll.reg[0x0e] & 32) != 0)))
				{
					opll.slot[SLOT_HH].type = 0;
					opll.slot[SLOT_HH].eg_mode = OPLL_EG_STATE.FINISH;
					opll.slot[SLOT_SD].eg_mode = OPLL_EG_STATE.FINISH;
					setPatch(opll, 7, opll.reg[0x37] >> 4);
				}
			}
			else if ((opll.reg[0x0e] & 32) != 0)
			{
				opll.patch_number[7] = 17;
				opll.slot[SLOT_HH].type = 1;
				opll.slot[SLOT_HH].eg_mode = OPLL_EG_STATE.FINISH;
				opll.slot[SLOT_SD].eg_mode = OPLL_EG_STATE.FINISH;
				setSlotPatch(opll.slot[SLOT_HH], opll.patch[17 * 2 + 0]);
				setSlotPatch(opll.slot[SLOT_SD], opll.patch[17 * 2 + 1]);
			}

			if ((opll.patch_number[8] & 0x10) != 0)
			{
				if (!((opll.slot_on_flag[SLOT_CYM] != 0 && opll.slot_on_flag[SLOT_TOM] != 0) | ((opll.reg[0x0e] & 32) != 0)))
				{
					opll.slot[SLOT_TOM].type = 0;
					opll.slot[SLOT_TOM].eg_mode = OPLL_EG_STATE.FINISH;
					opll.slot[SLOT_CYM].eg_mode = OPLL_EG_STATE.FINISH;
					setPatch(opll, 8, opll.reg[0x38] >> 4);
				}
			}
			else if ((opll.reg[0x0e] & 32) != 0)
			{
				opll.patch_number[8] = 18;
				opll.slot[SLOT_TOM].type = 1;
				opll.slot[SLOT_TOM].eg_mode = OPLL_EG_STATE.FINISH;
				opll.slot[SLOT_CYM].eg_mode = OPLL_EG_STATE.FINISH;
				setSlotPatch(opll.slot[SLOT_TOM], opll.patch[18 * 2 + 0]);
				setSlotPatch(opll.slot[SLOT_CYM], opll.patch[18 * 2 + 1]);
			}
		}
コード例 #6
0
ファイル: YM2413.cs プロジェクト: ddugovic/RASuite
		static void keyOff_CYM(OPLL opll)
		{
			if (opll.slot_on_flag[SLOT_CYM] != 0)
				slotOff(CAR(opll, 8));
		}
コード例 #7
0
ファイル: YM2413.cs プロジェクト: ddugovic/RASuite
		/* Set sustine parameter */
		static void setSustine(OPLL opll, int c, int sustine)
		{
			CAR(opll, c).sustine = sustine;
			if (MOD(opll, c).type != 0)
				MOD(opll, c).sustine = sustine;
		}
コード例 #8
0
ファイル: YM2413.cs プロジェクト: ddugovic/RASuite
		public YM2413(ChipType type)
		{
			MaxVolume = short.MaxValue;
			opll = OPLL_new(3579545, 44100, (int)type);
		}
コード例 #9
0
ファイル: YM2413.cs プロジェクト: ddugovic/RASuite
		/* Channel key on */
		static void keyOn(OPLL opll, int i)
		{
			if (opll.slot_on_flag[i * 2] == 0)
				slotOn(MOD(opll, i));
			if (opll.slot_on_flag[i * 2 + 1] == 0)
				slotOn(CAR(opll, i));
			opll.key_status[i] = 1;
		}
コード例 #10
0
ファイル: YM2413.cs プロジェクト: ddugovic/RASuite
		static uint RATE_ADJUST(double x) { return (rate == 49716 ? (uint)x : (uint)((double)(x) * clk / 72 / rate + 0.5)); }        /* added 0.5 to round the value*/

		static OPLL_SLOT MOD(OPLL o, int x) { return ((o).slot[(x) << 1]); }
コード例 #11
0
ファイル: YM2413.cs プロジェクト: ddugovic/RASuite
		static OPLL_SLOT CAR(OPLL o, int x) { return ((o).slot[((x) << 1) | 1]); }
コード例 #12
0
ファイル: YM2413.cs プロジェクト: ddugovic/RASuite
		public YM2413()
		{
			MaxVolume = short.MaxValue;
			opll = OPLL_new(3579545, 44100, 0);
		}
コード例 #13
0
ファイル: YM2413.cs プロジェクト: ddugovic/RASuite
		void OPLL_calc_stereo(OPLL opll, int[] output)
		{
			if (!opll.quality)
			{
				calc_stereo(opll, output);
				return;
			}

			while (opll.realstep > opll.oplltime)
			{
				opll.oplltime += opll.opllstep;
				opll.sprev[0] = opll.snext[0];
				opll.sprev[1] = opll.snext[1];
				calc_stereo(opll, opll.snext);
			}

			opll.oplltime -= opll.realstep;
			output[0] = (short)(((double)opll.snext[0] * (opll.opllstep - opll.oplltime)
								 + (double)opll.sprev[0] * opll.oplltime) / opll.opllstep);
			output[1] = (short)(((double)opll.snext[1] * (opll.opllstep - opll.oplltime)
								 + (double)opll.sprev[1] * opll.oplltime) / opll.opllstep);
		}
コード例 #14
0
ファイル: YM2413.cs プロジェクト: ddugovic/RASuite
		static void calc_stereo(OPLL opll, int[] output)
		{
			int[] b = new[] { 0, 0, 0, 0 };        /* Ignore, Right, Left, Center */
			int[] r = new[] { 0, 0, 0, 0 };        /* Ignore, Right, Left, Center */
			int i;

			update_ampm(opll);
			update_noise(opll);

			for (i = 0; i < 18; i++)
			{
				calc_phase(opll.slot[i], opll.lfo_pm);
				calc_envelope(opll.slot[i], opll.lfo_am);
			}

			for (i = 0; i < 6; i++)
				if ((opll.mask & OPLL_MASK_CH(i)) == 0 && (CAR(opll, i).eg_mode != OPLL_EG_STATE.FINISH))
					b[opll.pan[i]] += calc_slot_car(CAR(opll, i), calc_slot_mod(MOD(opll, i)));


			if (opll.patch_number[6] <= 15)
			{
				if ((opll.mask & OPLL_MASK_CH(6)) == 0 && (CAR(opll, 6).eg_mode != OPLL_EG_STATE.FINISH))
					b[opll.pan[6]] += calc_slot_car(CAR(opll, 6), calc_slot_mod(MOD(opll, 6)));
			}
			else
			{
				if ((opll.mask & OPLL_MASK_BD) == 0 && (CAR(opll, 6).eg_mode != OPLL_EG_STATE.FINISH))
					r[opll.pan[9]] += calc_slot_car(CAR(opll, 6), calc_slot_mod(MOD(opll, 6)));
			}

			if (opll.patch_number[7] <= 15)
			{
				if ((opll.mask & OPLL_MASK_CH(7)) == 0 && (CAR(opll, 7).eg_mode != OPLL_EG_STATE.FINISH))
					b[opll.pan[7]] += calc_slot_car(CAR(opll, 7), calc_slot_mod(MOD(opll, 7)));
			}
			else
			{
				if ((opll.mask & OPLL_MASK_HH) == 0 && (MOD(opll, 7).eg_mode != OPLL_EG_STATE.FINISH))
					r[opll.pan[10]] += calc_slot_hat(MOD(opll, 7), (int)CAR(opll, 8).pgout, opll.noise_seed & 1);
				if ((opll.mask & OPLL_MASK_SD) == 0 && (CAR(opll, 7).eg_mode != OPLL_EG_STATE.FINISH))
					r[opll.pan[11]] -= calc_slot_snare(CAR(opll, 7), opll.noise_seed & 1);
			}

			if (opll.patch_number[8] <= 15)
			{
				if ((opll.mask & OPLL_MASK_CH(8)) == 0 && (CAR(opll, 8).eg_mode != OPLL_EG_STATE.FINISH))
					b[opll.pan[8]] += calc_slot_car(CAR(opll, 8), calc_slot_mod(MOD(opll, 8)));
			}
			else
			{
				if ((opll.mask & OPLL_MASK_TOM) == 0 && (MOD(opll, 8).eg_mode != OPLL_EG_STATE.FINISH))
					r[opll.pan[12]] += calc_slot_tom(MOD(opll, 8));
				if ((opll.mask & OPLL_MASK_CYM) == 0 && (CAR(opll, 8).eg_mode != OPLL_EG_STATE.FINISH))
					r[opll.pan[13]] -= calc_slot_cym(CAR(opll, 8), MOD(opll, 7).pgout);
			}

			output[1] = (b[1] + b[3] + ((r[1] + r[3]) << 1)) << 3;
			output[0] = (b[2] + b[3] + ((r[2] + r[3]) << 1)) << 3;
		}
コード例 #15
0
ファイル: YM2413.cs プロジェクト: ddugovic/RASuite
		static void keyOff_TOM(OPLL opll)
		{
			if (opll.slot_on_flag[SLOT_TOM] != 0)
				slotOff(MOD(opll, 8));
		}
コード例 #16
0
ファイル: YM2413.cs プロジェクト: ddugovic/RASuite
		/* Channel key off */
		static void keyOff(OPLL opll, int i)
		{
			if (opll.slot_on_flag[i * 2 + 1] != 0)
				slotOff(CAR(opll, i));
			opll.key_status[i] = 0;
		}
コード例 #17
0
ファイル: YM2413.cs プロジェクト: ddugovic/RASuite
		static void keyOff_HH(OPLL opll)
		{
			if (opll.slot_on_flag[SLOT_HH] != 0)
				slotOff(MOD(opll, 7));
		}
コード例 #18
0
ファイル: YM2413.cs プロジェクト: ddugovic/RASuite
		static void keyOn_BD(OPLL opll)
		{
			keyOn(opll, 6);
		}
コード例 #19
0
ファイル: YM2413.cs プロジェクト: ddugovic/RASuite
		/* Change a voice */
		static void setPatch(OPLL opll, int i, int num)
		{
			opll.patch_number[i] = num;
			MOD(opll, i).patch = opll.patch[num * 2 + 0];
			CAR(opll, i).patch = opll.patch[num * 2 + 1];
		}
コード例 #20
0
ファイル: YM2413.cs プロジェクト: ddugovic/RASuite
		static void keyOn_TOM(OPLL opll)
		{
			if (opll.slot_on_flag[SLOT_TOM] == 0)
				slotOn(MOD(opll, 8));
		}
コード例 #21
0
ファイル: YM2413.cs プロジェクト: ddugovic/RASuite
		/* Volume : 6bit ( Volume register << 2 ) */
		static void setVolume(OPLL opll, int c, int volume)
		{
			CAR(opll, c).volume = volume;
		}
コード例 #22
0
ファイル: YM2413.cs プロジェクト: ddugovic/RASuite
		static void keyOn_HH(OPLL opll)
		{
			if (opll.slot_on_flag[SLOT_HH] == 0)
				slotOn2(MOD(opll, 7));
		}
コード例 #23
0
ファイル: YM2413.cs プロジェクト: ddugovic/RASuite
		/* Set Block data (block : 3bit ) */
		static void setBlock(OPLL opll, int c, int block)
		{
			CAR(opll, c).block = block;
			MOD(opll, c).block = block;
		}
コード例 #24
0
ファイル: YM2413.cs プロジェクト: ddugovic/RASuite
		static void keyOn_CYM(OPLL opll)
		{
			if (opll.slot_on_flag[SLOT_CYM] == 0)
				slotOn2(CAR(opll, 8));
		}
コード例 #25
0
ファイル: YM2413.cs プロジェクト: ddugovic/RASuite
		static void update_key_status(OPLL opll)
		{
			int ch;

			for (ch = 0; ch < 9; ch++)
				opll.slot_on_flag[ch * 2] = opll.slot_on_flag[ch * 2 + 1] = (opll.reg[0x20 + ch]) & 0x10;

			if ((opll.reg[0x0e] & 32) != 0)
			{
				opll.slot_on_flag[SLOT_BD1] |= (opll.reg[0x0e] & 0x10);
				opll.slot_on_flag[SLOT_BD2] |= (opll.reg[0x0e] & 0x10);
				opll.slot_on_flag[SLOT_SD] |= (opll.reg[0x0e] & 0x08);
				opll.slot_on_flag[SLOT_HH] |= (opll.reg[0x0e] & 0x01);
				opll.slot_on_flag[SLOT_TOM] |= (opll.reg[0x0e] & 0x04);
				opll.slot_on_flag[SLOT_CYM] |= (opll.reg[0x0e] & 0x02);
			}
		}
コード例 #26
0
ファイル: YM2413.cs プロジェクト: ddugovic/RASuite
		/* Drum key off */
		static void keyOff_BD(OPLL opll)
		{
			keyOff(opll, 6);
		}
コード例 #27
0
ファイル: YM2413.cs プロジェクト: ddugovic/RASuite
		OPLL OPLL_new(uint clk, uint rate, int type)
		{
			OPLL opll = new OPLL();
			int i;

			maketables(clk, rate);

			for (i = 0; i < 19 * 2; i++)
				opll.patch[i] = new OPLL_PATCH();

			opll.mask = 0;

			OPLL_reset(opll);
			OPLL_reset_patch(opll, type);

			return opll;
		}
コード例 #28
0
ファイル: YM2413.cs プロジェクト: ddugovic/RASuite
		static void keyOff_SD(OPLL opll)
		{
			if (opll.slot_on_flag[SLOT_SD] == 0)
				slotOff(CAR(opll, 7));
		}
コード例 #29
0
ファイル: YM2413.cs プロジェクト: ddugovic/RASuite
		/* Reset whole of OPLL except patch datas. */
		void OPLL_reset(OPLL opll)
		{
			int i;

			opll.adr = 0;
			opll.output = 0;

			opll.pm_phase = 0;
			opll.am_phase = 0;

			opll.noise_seed = 0xffff;
			opll.mask = 0;

			for (i = 0; i < 18; i++)
				OPLL_SLOT_reset(opll.slot[i], i % 2);

			for (i = 0; i < 9; i++)
			{
				opll.key_status[i] = 0;
				setPatch(opll, i, 0);
			}

			for (i = 0; i < 0x40; i++)
				OPLL_writeReg(opll, (uint)i, 0);

			opll.realstep = (uint)((1 << 31) / rate);
			opll.opllstep = (uint)((1 << 31) / (clk / 72));
			opll.oplltime = 0;
			for (i = 0; i < 14; i++)
				opll.pan[i] = 3;
			opll.sprev[0] = opll.sprev[1] = 0;
			opll.snext[0] = opll.snext[1] = 0;

		}
コード例 #30
0
ファイル: YM2413.cs プロジェクト: ddugovic/RASuite
		void OPLL_writeIO(OPLL opll, uint adr, uint val)
		{
			if ((adr & 1) != 0)
				OPLL_writeReg(opll, opll.adr, val);
			else
				opll.adr = val;
		}