⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ym2151.c

📁 十七种模拟器源代码 非常有用的作课程设计不可缺少的
💻 C
📖 第 1 页 / 共 4 页
字号:
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <math.h>#include "driver.h"#include "sasound.h"#include "ym2151.h"/*undef this to not use MAME timer system*///#define USE_MAME_TIMERS/*#define FM_EMU*/#ifdef FM_EMU	#define INLINE static __inline__	#ifdef USE_MAME_TIMERS		#undef USE_MAME_TIMERS	#endif#endif#ifdef USE_MAME_TIMERS	/*#define LOG_CYM_FILE*/	#ifdef LOG_CYM_FILE		FILE * cymfile = NULL;		void * cymfiletimer = 0;	#endif#endif/*operator data*/typedef struct{	unsigned int phase;		/*accumulated operator phase*/	unsigned int freq;		/*operator frequency*/	signed   int DT1v;		/*operator DT1 phase inc/decrement*/	unsigned int MUL;		/*phase multiply*/	unsigned int DT1;		/*DT1 * 32      */	unsigned int DT2;		/*DT2 index     */	signed   int *connect;	/*operator output 'direction'*//*Begin of channel specific data*//*note: each operator number 0 contains channel specific data*/	unsigned int FeedBack;	/*feedback shift value for operators 0 in each channel*/	signed   int FB;		/*operator self feedback value used only by operators 0*/	signed   int FB0;		/*previous output value*/	unsigned int KC;		/*operator KC (copied to all operators)*/	unsigned int KCindex;	/*speedup*/	unsigned int PMS;		/*channel PMS*/	unsigned int AMS;		/*channel AMS*//*End of channel specific data*/	unsigned int AMSmask;	/*LFO AMS enable mask*/	unsigned int state;		/*Envelope state: 4-attack(AR) 3-decay(D1R) 2-sustain(D2R) 1-release(RR) 0-off*/	unsigned int delta_AR;	/*volume delta for attack phase*/	unsigned int TL;		/*Total attenuation Level*/	signed   int volume;	/*operator attenuation level*/	unsigned int delta_D1R;	/*volume delta for decay phase*/	unsigned int D1L;		/*EG switches to D2R, when envelope reaches this level*/	unsigned int delta_D2R;	/*volume delta for sustain phase*/	unsigned int delta_RR;	/*volume delta for release phase*/	unsigned int key;		/*0=last key was KEY OFF, 1=last key was KEY ON*/	unsigned int KS;		/*Key Scale     */	unsigned int AR;		/*Attack rate   */	unsigned int D1R;		/*Decay rate    */	unsigned int D2R;		/*Sustain rate  */	unsigned int RR;		/*Release rate  */	unsigned int reserved0;	/**/	signed   int reserved1;	/**/	signed   int reserved2;	/**/} OscilRec;typedef struct{	OscilRec Oscils[32];	/*there are 32 operators in YM2151*/	unsigned int PAN[16];	/*channels output masks (0xffffffff = enable)*/	unsigned int LFOphase;	/*accumulated LFO phase         */	unsigned int LFOfrq;	/*LFO frequency                 */	unsigned int LFOwave;	/*LFO waveform (0-saw, 1-square, 2-triangle, 3-random noise)*/	unsigned int PMD;		/*LFO Phase Modulation Depth    */	unsigned int AMD;		/*LFO Amplitude Modulation Depth*/	unsigned int LFA;		/*current AM from LFO*/	signed   int LFP;		/*current PM from LFO*/	unsigned int test;		/*TEST register*/	unsigned int CT;		/*output control pins (bit7 CT2, bit6 CT1)*/	unsigned int noise;		/*noise register (bit 7 - noise enable, bits 4-0 - noise period*/	unsigned int noiseRNG;	/*17 bit noise shift register*/	unsigned int noise_p;	/*noise 'phase'*/	unsigned int noise_f;	/*noise period*/	unsigned int CSMreq;	/*CSM KEYON/KEYOFF sequence request*/	unsigned int IRQenable;	/*IRQ enable for timer B (bit 3) and timer A (bit 2); bit 7 - CSM mode (keyon to all slots, everytime timer A overflows)*/	unsigned int status;	/*chip status (BUSY, IRQ Flags)*/#ifdef USE_MAME_TIMERS	void *TimATimer,*TimBTimer;	/*ASG 980324 -- added for tracking timers*/	double TimerATime[1024];	/*Timer A times for MAME*/	double TimerBTime[256];		/*Timer B times for MAME*/#else	int TimA,TimB;				/*timer A,B enable (0-disabled)*/	signed int TimAVal,TimBVal;	/*current value of timer*/	unsigned int TimerA[1024];	/*Timer A deltas*/	unsigned int TimerB[256];	/*Timer B deltas*/#endif	unsigned int TimAIndex;		/*Timer A index*/	unsigned int TimBIndex;		/*Timer B index*/	unsigned int TimAOldIndex;	/*Timer A previous index*/	unsigned int TimBOldIndex;	/*Timer B previous index*/	/*	*   Frequency-deltas to get the closest frequency possible.	*   There're 11 octaves because of DT2 (max 950 cents over base frequency)	*   and LFO phase modulation (max 800 cents below AND over base frequency)	*   Summary:   octave  explanation	*              0       note code - LFO PM	*              1       note code	*              2       note code	*              3       note code	*              4       note code	*              5       note code	*              6       note code	*              7       note code	*              8       note code	*              9       note code + DT2 + LFO PM	*              10      note code + DT2 + LFO PM	*/	unsigned int freq[11*768];/*11 octaves, 768 'cents' per octave*/	/*	*   Frequency deltas for DT1. These deltas alter operator frequency	*   after it has been taken from frequency-deltas table.	*/	signed   int DT1freq[8*32];		/*8 DT1 levels, 32 KC values*/	unsigned int EG_tab [32+64+32];	/*Envelope Generator deltas (32 + 64 rates + 32 RKS)*/	unsigned int LFOfreq[256];		/*LFO frequency deltas*/	unsigned int noise_tab[32];		/*17bit Noise Generator periods*/	void (*irqhandler)(int irq);	/*IRQ function handler*/	mem_write_handler porthandler;	/*port write function handler*/	unsigned int clock;				/*chip clock in Hz (passed from 2151intf.c)*/	unsigned int sampfreq;			/*sampling frequency in Hz (passed from 2151intf.c)*/} YM2151;/***  Shifts below are subject to change when sampling frequency changes...*/#define FREQ_SH			16  /* 16.16 fixed point (frequency calculations) */#define ENV_SH			16  /* 16.16 fixed point (envelope calculations)  */#define LFO_SH			23  /*  9.23 fixed point (LFO calculations)       */#define TIMER_SH		16  /* 16.16 fixed point (timers calculations)    */#define FREQ_MASK		((1<<FREQ_SH)-1)#define ENV_MASK		((1<<ENV_SH)-1)#define ENV_BITS		10#define ENV_LEN			(1<<ENV_BITS)#define ENV_STEP		(128.0/ENV_LEN)#define ENV_QUIET		((int)(0x68/(ENV_STEP)))#define MAX_ATT_INDEX	((ENV_LEN<<ENV_SH)-1) /*1023.ffff*/#define MIN_ATT_INDEX	(      (1<<ENV_SH)-1) /*   0.ffff*/#define EG_ATT			4#define EG_DEC			3#define EG_SUS			2#define EG_REL			1#define EG_OFF			0#define SIN_BITS		10#define SIN_LEN			(1<<SIN_BITS)#define SIN_MASK		(SIN_LEN-1)#define TL_RES_LEN		(256) /* 8 bits addressing (real chip) */#define LFO_BITS		9#define LFO_LEN			(1<<LFO_BITS)#define LFO_MASK		(LFO_LEN-1)#if (SAMPLE_BITS==16)	#define FINAL_SH	(0)	#define MAXOUT		(+32767)	#define MINOUT		(-32768)#else	#define FINAL_SH	(8)	#define MAXOUT		(+127)	#define MINOUT		(-128)#endif/* TL_TAB_LEN is calculated as: * 13 - sinus amplitude bits  (Y axis) * 2  - sinus sign bit        (Y axis) * ENV_LEN - sinus resolution (X axis)*/#define TL_TAB_LEN (13*2*TL_RES_LEN)static signed int TL_TAB[TL_TAB_LEN];/* sin waveform table in 'decibel' scale*/static unsigned int sin_tab[SIN_LEN];/* four AM/PM LFO waveforms (8 in total)*/static unsigned int lfo_tab[LFO_LEN*4*2];/* LFO amplitude modulation depth table (128 levels)*/static unsigned int lfo_md_tab[128];/* translate from D1L to volume index (16 D1L levels)*/static unsigned int D1L_tab[16];/* *   DT2 defines offset in cents from base note * *   This table defines offset in frequency-deltas table. *   User's Manual page 22 * *   Values below were calculated using formula: value =  orig.val / 1.5625 * *	DT2=0 DT2=1 DT2=2 DT2=3 *	0     600   781   950*/static unsigned int DT2_tab[4] = { 0, 384, 500, 608 };/* *   DT1 defines offset in Hertz from base note *   This table is converted while initialization... *   Detune table in YM2151 User's Manual is wrong (checked against the real chip)*/static unsigned char DT1_tab[4*32] = { /* 4*32 DT1 values *//* DT1=0 */  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* DT1=1 */  0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2,  2, 3, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 8, 8, 8, 8,/* DT1=2 */  1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5,  5, 6, 6, 7, 8, 8, 9,10,11,12,13,14,16,16,16,16,/* DT1=3 */  2, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7,  8, 8, 9,10,11,12,13,14,16,17,19,20,22,22,22,22};static unsigned short phaseinc_rom[768]={1299,1300,1301,1302,1303,1304,1305,1306,1308,1309,1310,1311,1313,1314,1315,1316,1318,1319,1320,1321,1322,1323,1324,1325,1327,1328,1329,1330,1332,1333,1334,1335,1337,1338,1339,1340,1341,1342,1343,1344,1346,1347,1348,1349,1351,1352,1353,1354,1356,1357,1358,1359,1361,1362,1363,1364,1366,1367,1368,1369,1371,1372,1373,1374,1376,1377,1378,1379,1381,1382,1383,1384,1386,1387,1388,1389,1391,1392,1393,1394,1396,1397,1398,1399,1401,1402,1403,1404,1406,1407,1408,1409,1411,1412,1413,1414,1416,1417,1418,1419,1421,1422,1423,1424,1426,1427,1429,1430,1431,1432,1434,1435,1437,1438,1439,1440,1442,1443,1444,1445,1447,1448,1449,1450,1452,1453,1454,1455,1458,1459,1460,1461,1463,1464,1465,1466,1468,1469,1471,1472,1473,1474,1476,1477,1479,1480,1481,1482,1484,1485,1486,1487,1489,1490,1492,1493,1494,1495,1497,1498,1501,1502,1503,1504,1506,1507,1509,1510,1512,1513,1514,1515,1517,1518,1520,1521,1523,1524,1525,1526,1528,1529,1531,1532,1534,1535,1536,1537,1539,1540,1542,1543,1545,1546,1547,1548,1550,1551,1553,1554,1556,1557,1558,1559,1561,1562,1564,1565,1567,1568,1569,1570,1572,1573,1575,1576,1578,1579,1580,1581,1583,1584,1586,1587,1590,1591,1592,1593,1595,1596,1598,1599,1601,1602,1604,1605,1607,1608,1609,1610,1613,1614,1615,1616,1618,1619,1621,1622,1624,1625,1627,1628,1630,1631,1632,1633,1637,1638,1639,1640,1642,1643,1645,1646,1648,1649,1651,1652,1654,1655,1656,1657,1660,1661,1663,1664,1666,1667,1669,1670,1672,1673,1675,1676,1678,1679,1681,1682,1685,1686,1688,1689,1691,1692,1694,1695,1697,1698,1700,1701,1703,1704,1706,1707,1709,1710,1712,1713,1715,1716,1718,1719,1721,1722,1724,1725,1727,1728,1730,1731,1734,1735,1737,1738,1740,1741,1743,1744,1746,1748,1749,1751,1752,1754,1755,1757,1759,1760,1762,1763,1765,1766,1768,1769,1771,1773,1774,1776,1777,1779,1780,1782,1785,1786,1788,1789,1791,1793,1794,1796,1798,1799,1801,1802,1804,1806,1807,1809,1811,1812,1814,1815,1817,1819,1820,1822,1824,1825,1827,1828,1830,1832,1833,1835,1837,1838,1840,1841,1843,1845,1846,1848,1850,1851,1853,1854,1856,1858,1859,1861,1864,1865,1867,1868,1870,1872,1873,1875,1877,1879,1880,1882,1884,1885,1887,1888,1891,1892,1894,1895,1897,1899,1900,1902,1904,1906,1907,1909,1911,1912,1914,1915,1918,1919,1921,1923,1925,1926,1928,1930,1932,1933,1935,1937,1939,1940,1942,1944,1946,1947,1949,1951,1953,1954,1956,1958,1960,1961,1963,1965,1967,1968,1970,1972,1975,1976,1978,1980,1982,1983,1985,1987,1989,1990,1992,1994,1996,1997,1999,2001,2003,2004,2006,2008,2010,2011,2013,2015,2017,2019,2021,2022,2024,2026,2028,2029,2032,2033,2035,2037,2039,2041,2043,2044,2047,2048,2050,2052,2054,2056,2058,2059,2062,2063,2065,2067,2069,2071,2073,2074,2077,2078,2080,2082,2084,2086,2088,2089,2092,2093,2095,2097,2099,2101,2103,2104,2107,2108,2110,2112,2114,2116,2118,2119,2122,2123,2125,2127,2129,2131,2133,2134,2137,2139,2141,2142,2145,2146,2148,2150,2153,2154,2156,2158,2160,2162,2164,2165,2168,2170,2172,2173,2176,2177,2179,2181,2185,2186,2188,2190,2192,2194,2196,2197,2200,2202,2204,2205,2208,2209,2211,2213,2216,2218,2220,2222,2223,2226,2227,2230,2232,2234,2236,2238,2239,2242,2243,2246,2249,2251,2253,2255,2256,2259,2260,2263,2265,2267,2269,2271,2272,2275,2276,2279,2281,2283,2285,2287,2288,2291,2292,2295,2297,2299,2301,2303,2304,2307,2308,2311,2315,2317,2319,2321,2322,2325,2326,2329,2331,2333,2335,2337,2338,2341,2342,2345,2348,2350,2352,2354,2355,2358,2359,2362,2364,2366,2368,2370,2371,2374,2375,2378,2382,2384,2386,2388,2389,2392,2393,2396,2398,2400,2402,2404,2407,2410,2411,2414,2417,2419,2421,2423,2424,2427,2428,2431,2433,2435,2437,2439,2442,2445,2446,2449,2452,2454,2456,2458,2459,2462,2463,2466,2468,2470,2472,2474,2477,2480,2481,2484,2488,2490,2492,2494,2495,2498,2499,2502,2504,2506,2508,2510,2513,2516,2517,2520,2524,2526,2528,2530,2531,2534,2535,2538,2540,2542,2544,2546,2549,2552,2553,2556,2561,2563,2565,2567,2568,2571,2572,2575,2577,2579,2581,2583,2586,2589,2590,2593};static YM2151 * YMPSG = NULL;	/* array of YM2151's */static unsigned int YMNumChips;	/* total # of YM2151's emulated *//*these variables stay here because of speedup purposes only */static YM2151 * PSG;static signed int chanout[8];static signed int c1,m2,c2; /*Phase Modulation input for operators 2,3,4*//*save output as raw 16-bit sample*//*#define SAVE_SAMPLE*//*#define SAVE_SEPARATE_CHANNELS*/#if defined SAVE_SAMPLE || defined SAVE_SEPARATE_CHANNELSstatic FILE *sample[9];#endif/* own PI definition */#ifdef PI	#undef PI#endif#define PI 3.14159265358979323846static void init_tables(void){	signed int i,x;	signed int n;	double o,m;	for (x=0; x<TL_RES_LEN; x++)	{		m = (1<<16) / pow(2, (x+1) * (ENV_STEP/4.0) / 8.0);		m = floor(m);		/* we never reach (1<<16) here due to the (x+1) */		/* result fits within 16 bits at maximum */		n = (int)m;		/* 16 bits here */		n >>= 4;		/* 12 bits here */		if (n&1)		/* round to closest */			n = (n>>1)+1;		else			n = n>>1;						/* 11 bits here (rounded) */		n <<= 2;		/* 13 bits here (as in real chip) */		TL_TAB[ x*2 + 0 ] = n;		TL_TAB[ x*2 + 1 ] = -TL_TAB[ x*2 + 0 ];		for (i=1; i<13; i++)		{			TL_TAB[ x*2+0 + i*2*TL_RES_LEN ] =  TL_TAB[ x*2+0 ]>>i;			TL_TAB[ x*2+1 + i*2*TL_RES_LEN ] = -TL_TAB[ x*2+0 + i*2*TL_RES_LEN ];		}	#if 0			logerror("tl %04i", x);			for (i=0; i<13; i++)				logerror(", [%02i] %4x", i*2, TL_TAB[ x*2 /*+1*/ + i*2*TL_RES_LEN ]);			logerror("\n");		}	#endif	}	/*logerror("TL_TAB_LEN = %i (%i bytes)\n",TL_TAB_LEN, (int)sizeof(TL_TAB));*/	for (i=0; i<SIN_LEN; i++)	{		/* non-standard sinus */		m = sin( ((i*2)+1) * PI / SIN_LEN ); /* checked against the real chip */		/* we never reach zero here due to ((i*2)+1) */		if (m>0.0)			o = 8*log(1.0/m)/log(2);  /* convert to 'decibels' */		else			o = 8*log(-1.0/m)/log(2); /* convert to 'decibels' */		o = o / (ENV_STEP/4);		n = (int)(2.0*o);		if (n&1)		/* round to closest */			n = (n>>1)+1;		else			n = n>>1;		sin_tab[ i ] = n*2 + (m>=0.0? 0: 1 );		/*logerror("sin [%4i]= %4i (TL_TAB value=%5i)\n", i, sin_tab[i],TL_TAB[sin_tab[i]]);*/	}	/*logerror("ENV_QUIET= %08x\n",ENV_QUIET );*/	/* calculate LFO AM waveforms*/	for (x=0; x<4; x++)	{	    for (i=0; i<LFO_LEN; i++)	    {		switch (x)		{		case 0:	/* saw (255 down to 0) */			m = 255 - (i/2);			break;		case 1: /* square (255,0) */			if (i<256)				m = 255;			else				m = 0;			break;		case 2: /* triangle (255 down to 0, up to 255) */			if (i<256)				m = 255 - i;			else				m = i - 256;			break;		case 3: /* random (range 0 to 255) */			m = ((int)rand()) & 255;			break;		}		/* we reach m = zero here !!!*/		if (m>0.0)			o = 8*log(255.0/m)/log(2);  /* convert to 'decibels' */		else		{			if (m<0.0)				o = 8*log(-255.0/m)/log(2); /* convert to 'decibels' */			else				o = 8*log(255.0/0.01)/log(2); /* small number */		}		o = o / (ENV_STEP/4);		n = (int)(2.0*o);		if (n&1)		/* round to closest */			n = (n>>1)+1;		else			n = n>>1;		lfo_tab[ x*LFO_LEN*2 + i*2 ] = n*2 + (m>=0.0? 0: 1 );		/*logerror("lfo am waveofs[%i] %04i = %i\n", x, i*2, lfo_tab[ x*LFO_LEN*2 + i*2 ] );*/	    }	}	for (i=0; i<128; i++)	{		m = i*2; /*m=0,2,4,6,8,10,..,252,254*/		/* we reach m = zero here !!!*/		if (m>0.0)			o = 8*log(8192.0/m)/log(2);  /* convert to 'decibels' */		else			o = 8*log(8192.0/0.01)/log(2); /* small number (m=0)*/		o = o / (ENV_STEP/4);		n = (int)(2.0*o);		if (n&1)		/* round to closest */			n = (n>>1)+1;		else			n = n>>1;		lfo_md_tab[ i ] = n*2;		/*logerror("lfo_md_tab[%i](%i) = ofs %i shr by %i\n", i, i*2, (lfo_md_tab[i]>>1)&255, lfo_md_tab[i]>>9 );*/	}	/* calculate LFO PM waveforms*/	for (x=0; x<4; x++)	{	    for (i=0; i<LFO_LEN; i++)	    {		switch (x)		{		case 0:	/* saw (0 to 127, -128 to -1) */			if (i<256)				m = (i/2);			else				m = (i/2)-256;			break;		case 1: /* square (127,-128) */			if (i<256)				m = 127;			else				m = -128;			break;		case 2: /* triangle (0 to 127,127 to -128,-127 to 0) */			if (i<128)				m = i; /*0 to 127*/			else			{				if (i<384)					m = 255 - i; /*127 down to -128*/				else					m = i - 511; /*-127 to 0*/			}			break;		case 3: /* random (range -128 to 127) */			m = ((int)rand()) & 255;			m -=128;			break;		}		/* we reach m = zero here !!!*/		if (m>0.0)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -