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

📄 ym2151.c

📁 十七种模拟器源代码 非常有用的作课程设计不可缺少的
💻 C
📖 第 1 页 / 共 4 页
字号:
			o = 8*log(127.0/m)/log(2);  /* convert to 'decibels' */		else		{			if (m<0.0)				o = 8*log(-128.0/m)/log(2); /* convert to 'decibels' */			else				o = 8*log(127.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 + 1 ] = n*2 + (m>=0.0? 0: 1 );		/*logerror("lfo pm waveofs[%i] %04i = %i\n", x, i*2+1, lfo_tab[ x*LFO_LEN*2 + i*2 + 1 ] );*/	    }	}	/* calculate D1L_tab table */	for (i=0; i<16; i++)	{		m = (i!=15 ? i : i+16) * (4.0/ENV_STEP);   /*every 3 'dB' except for all bits = 1 = 45dB+48dB*/		D1L_tab[i] = (unsigned int)(m * (1<<ENV_SH));		/*logerror("D1L_tab[%02x]=%08x\n",i,D1L_tab[i] );*/	}#ifdef SAVE_SAMPLEsample[8]=fopen("sampsum.raw","ab");#endif#ifdef SAVE_SEPARATE_CHANNELSsample[0]=fopen("samp0.raw","wb");sample[1]=fopen("samp1.raw","wb");sample[2]=fopen("samp2.raw","wb");sample[3]=fopen("samp3.raw","wb");sample[4]=fopen("samp4.raw","wb");sample[5]=fopen("samp5.raw","wb");sample[6]=fopen("samp6.raw","wb");sample[7]=fopen("samp7.raw","wb");#endif}static void init_chip_tables(YM2151 *chip){	int i,j;	double mult,pom,pom2,clk,phaseinc,Hz;	double scaler;	/* formula below is true for chip clock=3579545 */	/* so we need to scale its output accordingly to the chip clock */	/*scaler = (double)chip->clock / 3579545.0;*/	scaler = ( (double)chip->clock / 64.0 ) / ( (double)chip->sampfreq );#if 0	logerror("scaler    = %20.15f\n", scaler);	logerror("scalerold = %20.15f\n", (double)chip->clock / 3579545.0 );#endif	/*this loop calculates Hertz values for notes from c-0 to b-7*/	/*including 64 'cents' (100/64 that is 1.5625 of real cent) per note*/	/* i*100/64/1200 is equal to i/768 */	/* real chip works with 10 bits fixed point values (10.10)*/	mult = (1<<(FREQ_SH-10)); /* -10 because phaseinc_rom table values are already in 10.10 format */	for (i=0; i<768; i++)	{		/* 3.4375 Hz is note A; C# is 4 semitones higher */		Hz = 1000;#if 0/* Hz is close, but not perfect */		/*Hz = scaler * 3.4375 * pow (2, (i + 4 * 64 ) / 768.0 ); */		/* calculate phase increment */		phaseinc = (Hz*SIN_LEN) / (double)chip->sampfreq;#endif		phaseinc = phaseinc_rom[i];	/*real chip phase increment*/		phaseinc *= scaler;			/*adjust*/		/*octave 2 - reference octave*/		chip->freq[ 768+2*768+i ] = ((int)(phaseinc*mult)) & 0xffffffc0; /*adjust to X.10 fixed point*/		/*octave 0 and octave 1*/		for (j=0; j<2; j++)		{			chip->freq[768 + j*768 + i] = (chip->freq[ 768+2*768+i ] >> (2-j) ) & 0xffffffc0; /*adjust to X.10 fixed point*/		}		/*octave 3 to 7*/		for (j=3; j<8; j++)		{			chip->freq[768 + j*768 + i] = chip->freq[ 768+2*768+i ] << (j-2);		}	#if 0			pom = (double)chip->freq[ 768+2*768+i ] / ((double)(1<<FREQ_SH));			pom = pom * (double)chip->sampfreq / (double)SIN_LEN;			logerror("1freq[%4i][%08x]= real %20.15f Hz  emul %20.15f Hz\n", i, chip->freq[ 768+2*768+i ], Hz, pom);	#endif	}	/*octave -1 (all equal to: oct 0, KC 00, KF 00) */	for (i=0; i<768; i++)	{		chip->freq[ 0*768 + i ] = chip->freq[1*768+0];	}	/*octave 8 and 9 (all equal to: oct 7, _KC_14_, _KF_63_) */	for (j=8; j<10; j++)	{		for (i=0; i<768; i++)		{			chip->freq[768+ j*768 + i ] = chip->freq[768 + 8*768 -1];		}	}	#if 0		for (i=0; i<11*768; i++)		{			pom = (double)chip->freq[i] / ((double)(1<<FREQ_SH));			pom = pom * (double)chip->sampfreq / (double)SIN_LEN;			logerror("freq[%4i][%08x]= emul %20.15f Hz\n", i, chip->freq[i], pom);		}	#endif	mult = (1<<FREQ_SH);	for (j=0; j<4; j++)	{		for (i=0; i<32; i++)		{			Hz = ( (double)DT1_tab[j*32+i] * ((double)chip->clock/64.0) ) / (double)(1<<20);			/*calculate phase increment*/			phaseinc = (Hz*SIN_LEN) / (double)chip->sampfreq;			/*positive and negative values*/			chip->DT1freq[ (j+0)*32 + i ] = (int)(phaseinc * mult);			chip->DT1freq[ (j+4)*32 + i ] = -chip->DT1freq[ (j+0)*32 + i ];		#if 0			{				int x = j*32 + i;				pom = (double)chip->DT1freq[x] / mult;				pom = pom * (double)chip->sampfreq / (double)SIN_LEN;				logerror("DT1(%03i)[%02i %02i][%08x]= real %19.15f Hz  emul %19.15f Hz\n",						 x, j, i, chip->DT1freq[x], Hz, pom);			}		#endif		}	}	mult = (1<<LFO_SH);	clk  = (double)chip->clock;	for (i=0; i<256; i++)	{		j = i & 0x0f;		pom = fabs(  (clk/65536/(1<<(i/16)) ) - (clk/65536/32/(1<<(i/16)) * (j+1)) );		/*calculate phase increment*/		chip->LFOfreq[0xff-i] = (unsigned int)(( (pom*LFO_LEN) / (double)chip->sampfreq ) * mult); /*fixed point*/		/*logerror("LFO[%02x] (%08x)= real %20.15f Hz  emul %20.15f Hz\n",0xff-i, chip->LFOfreq[0xff-i], pom,			(((double)chip->LFOfreq[0xff-i] / mult) * (double)chip->sampfreq ) / (double)LFO_LEN );*/	}	for (i=0; i<34; i++)		chip->EG_tab[i] = 0;		/* infinity */	for (i=2; i<64; i++)	{		pom2 = (double)chip->clock / (double)chip->sampfreq;		if (i<60) pom2 *= ( 1 + (i&3)*0.25 );		pom2 *= 1<<((i>>2));		pom2 /= 768.0 * 1024.0;		pom2 *= (double)(1<<ENV_SH);		chip->EG_tab[32+i] = (unsigned int)pom2;	#if 0		logerror("Rate %2i %1i  Decay [real %11.4f ms][emul %11.4f ms][d=%08x]\n",i>>2, i&3,			( ((double)(ENV_LEN<<ENV_SH)) / pom2 )                       * (1000.0 / (double)chip->sampfreq),			( ((double)(ENV_LEN<<ENV_SH)) / (double)chip->EG_tab[32+i] ) * (1000.0 / (double)chip->sampfreq), chip->EG_tab[32+i] );	#endif	}	for (i=0; i<32; i++)	{		chip->EG_tab[ 32+64+i ] = chip->EG_tab[32+63];	}	/* precalculate timers' deltas */	/* User's Manual pages 15,16  */	mult = (1<<TIMER_SH);	for (i=0; i<1024; i++)	{		/* ASG 980324: changed to compute both TimerA and TimerATime */		pom= ( 64.0  *  (1024.0-i) / (double)chip->clock );		#ifdef USE_MAME_TIMERS			chip->TimerATime[i] = pom;		#else			chip->TimerA[i] = (unsigned int)(pom * (double)chip->sampfreq * mult);  /*number of samples that timer period takes (fixed point) */		#endif	}	for (i=0; i<256; i++)	{		/* ASG 980324: changed to compute both TimerB and TimerBTime */		pom= ( 1024.0 * (256.0-i)  / (double)chip->clock );		#ifdef USE_MAME_TIMERS			chip->TimerBTime[i] = pom;		#else			chip->TimerB[i] = (unsigned int)(pom * (double)chip->sampfreq * mult);  /*number of samples that timer period takes (fixed point) */		#endif	}	/* calculate noise periods table */	scaler = ( (double)chip->clock / 64.0 ) / ( (double)chip->sampfreq );	for (i=0; i<32; i++)	{		j = (i!=31 ? i : 30);   /*period 30 and 31 are the same*/		j = 32-j;		j = (int)(65536.0 / (double)(j*32.0));	/*number of samples per one shift of the shift register*/		/*chip->noise_tab[i] = j * 64;*/	/*number of chip clock cycles per one shift*/		chip->noise_tab[i] = (unsigned int)(j * 64 * scaler);		/*logerror("noise_tab[%02x]=%08x\n", i, chip->noise_tab[i]);*/	}}/*#define RESET_FEEDBACK_ON_KEYON*/INLINE void envelope_KONKOFF(OscilRec * op, int v){	if (v&0x08)	{		if (!op->key)		{			op->key   = 1;      /*KEYON'ed*/			op->phase = 0;      /*clear phase */			op->state = EG_ATT; /*KEY ON = attack*/		}	}	else	{		if (op->key)		{			op->key   = 0;      /*KEYOFF'ed*/			if (op->state>EG_REL)				op->state = EG_REL; /*release*/		}	}	op+=8;	if (v&0x20)	{		if (!op->key)		{			op->key   = 1;			op->phase = 0;			op->state = EG_ATT;		}	}	else	{		if (op->key)		{			op->key   = 0;			if (op->state>EG_REL)				op->state = EG_REL;		}	}	op+=8;	if (v&0x10)	{		if (!op->key)		{			op->key   = 1;			op->phase = 0;			op->state = EG_ATT;		}	}	else	{		if (op->key)		{			op->key   = 0;			if (op->state>EG_REL)				op->state = EG_REL;		}	}	op+=8;	if (v&0x40)	{		if (!op->key)		{			op->key   = 1;			op->phase = 0;			op->state = EG_ATT;		}	}	else	{		if (op->key)		{			op->key   = 0;			if (op->state>EG_REL)				op->state = EG_REL;		}	}}#ifdef USE_MAME_TIMERSstatic void timer_callback_a (int n){	YM2151 *chip = &YMPSG[n];	chip->TimATimer = timer_set (chip->TimerATime[ chip->TimAIndex ], n, timer_callback_a);	chip->TimAOldIndex = chip->TimAIndex;	if (chip->IRQenable & 0x04)	{		int oldstate = chip->status & 3;		chip->status |= 1;		if ((!oldstate) && (chip->irqhandler)) (*chip->irqhandler)(1);	}	if (chip->IRQenable & 0x80)		chip->CSMreq = 2;	/*request KEYON/KEYOFF sequence*/}static void timer_callback_b (int n){	YM2151 *chip = &YMPSG[n];	chip->TimBTimer = timer_set (chip->TimerBTime[ chip->TimBIndex ], n, timer_callback_b);	chip->TimBOldIndex = chip->TimBIndex;	if (chip->IRQenable & 0x08)	{		int oldstate = chip->status & 3;		chip->status |= 2;		if ((!oldstate) && (chip->irqhandler)) (*chip->irqhandler)(1);	}}#if 0static void timer_callback_chip_write_busy (int n){	YM2151 *chip = &YMPSG[n];	chip->status &= 0x7f;	/*reset busy flag*/}#endif#endifINLINE void set_connect( OscilRec *om1, int v, int cha){	OscilRec *om2 = om1+8;	OscilRec *oc1 = om1+16;	/*OscilRec *oc2 = om1+24;*/	/*oc2->connect = &chanout[cha];*/	/* set connect algorithm */	switch( v & 7 )	{	case 0:		/* M1---C1---M2---C2---OUT */		om1->connect = &c1;		oc1->connect = &m2;		om2->connect = &c2;		break;	case 1:		/* M1-+-M2---C2---OUT */		/* C1-+               */		om1->connect = &m2;		oc1->connect = &m2;		om2->connect = &c2;		break;	case 2:		/* M1------+-C2---OUT */		/* C1---M2-+          */		om1->connect = &c2;		oc1->connect = &m2;		om2->connect = &c2;		break;	case 3:		/* M1---C1-+-C2---OUT */		/* M2------+          */		om1->connect = &c1;		oc1->connect = &c2;		om2->connect = &c2;		break;	case 4:		/* M1---C1-+--OUT */		/* M2---C2-+      */		om1->connect = &c1;		oc1->connect = &chanout[cha];		om2->connect = &c2;		break;	case 5:		/*    +-C1-+     */		/* M1-+-M2-+-OUT */		/*    +-C2-+     */		om1->connect = 0;	/* special mark */		oc1->connect = &chanout[cha];		om2->connect = &chanout[cha];		break;	case 6:		/* M1---C1-+     */		/*      M2-+-OUT */		/*      C2-+     */		om1->connect = &c1;		oc1->connect = &chanout[cha];		om2->connect = &chanout[cha];		break;	case 7:		/* M1-+     */		/* C1-+-OUT */		/* M2-+     */		/* C2-+     */		om1->connect = &chanout[cha];		oc1->connect = &chanout[cha];		om2->connect = &chanout[cha];		break;	}}INLINE void refresh_EG( YM2151 *chip, OscilRec * op){	unsigned int kc;	unsigned int v;	kc = op->KC;	/*v = 32 + 2*RATE + RKS (max 126)*/	v = kc >> op->KS;	if ((op->AR+v) < 32+62)		op->delta_AR  = chip->EG_tab[ op->AR + v];	else		op->delta_AR  = MAX_ATT_INDEX+1;	op->delta_D1R = chip->EG_tab[op->D1R + v];	op->delta_D2R = chip->EG_tab[op->D2R + v];	op->delta_RR  = chip->EG_tab[ op->RR + v];	op+=8;	v = kc >> op->KS;	if ((op->AR+v) < 32+62)		op->delta_AR  = chip->EG_tab[ op->AR + v];	else		op->delta_AR  = MAX_ATT_INDEX+1;	op->delta_D1R = chip->EG_tab[op->D1R + v];	op->delta_D2R = chip->EG_tab[op->D2R + v];	op->delta_RR  = chip->EG_tab[ op->RR + v];	op+=8;	v = kc >> op->KS;	if ((op->AR+v) < 32+62)		op->delta_AR  = chip->EG_tab[ op->AR + v];	else		op->delta_AR  = MAX_ATT_INDEX+1;	op->delta_D1R = chip->EG_tab[op->D1R + v];	op->delta_D2R = chip->EG_tab[op->D2R + v];	op->delta_RR  = chip->EG_tab[ op->RR + v];	op+=8;	v = kc >> op->KS;	if ((op->AR+v) < 32+62)		op->delta_AR  = chip->EG_tab[ op->AR + v];	else		op->delta_AR  = MAX_ATT_INDEX+1;	op->delta_D1R = chip->EG_tab[op->D1R + v];	op->delta_D2R = chip->EG_tab[op->D2R + v];	op->delta_RR  = chip->EG_tab[ op->RR + v];}/* write a register on YM2151 chip number 'n' */void YM2151WriteReg(int n, int r, int v){	YM2151 *chip = &(YMPSG[n]);	OscilRec *op = &chip->Oscils[ r&0x1f ];	/*adjust bus to 8 bits*/	r &= 0xff;	v &= 0xff;#if 0	/*There's no info on what YM2151 really does when busy flag is set*/	if ( chip->status & 0x80 ) return;	timer_set ( 68.0 / (double)chip->clock, n, timer_callback_chip_write_busy);	chip->status |= 0x80;    /* set busy flag for 68 chip clock cycles */#endif#ifdef LOG_CYM_FILE	if ((cymfile) && (r!=0) )	{		fputc( (unsigned char)r, cymfile );		fputc( (unsigned char)v, cymfile );	}#endif	switch(r & 0xe0){	case 0x00:		switch(r){		case 0x01: /*LFO reset(bit 1), Test Register (other bits)*/			chip->test = v;			if (v&2) chip->LFOphase = 0;			break;		case 0x08:			envelope_KONKOFF(&chip->Oscils[ v&7 ], v );			break;		case 0x0f: /*noise mode enable, noise period*/			chip->noise = v;

⌨️ 快捷键说明

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