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

📄 sound.c

📁 日本的手持pda源码.wince下使用,完全开源
💻 C
字号:
#include "defs.h"#include "pcm.h"#include "sound.h"#include "cpu.h"#include "hw.h"#include "regs.h"#include "noise.h"const static byte dmgwave[16] ={	0xac, 0xdd, 0xda, 0x48,	0x36, 0x02, 0xcf, 0x16,	0x2c, 0x04, 0xe5, 0x2c,	0xac, 0xdd, 0xda, 0x48};const static byte cgbwave[16] ={	0x00, 0xff, 0x00, 0xff,	0x00, 0xff, 0x00, 0xff,	0x00, 0xff, 0x00, 0xff,	0x00, 0xff, 0x00, 0xff,};const static byte sqwave[4][8] ={	{  0, 0,-1, 0, 0, 0, 0, 0 },	{  0,-1,-1, 0, 0, 0, 0, 0 },	{ -1,-1,-1,-1, 0, 0, 0, 0 },	{ -1, 0, 0,-1,-1,-1,-1,-1 }};
const static int freqtab[8] ={	(1<<14)*2,	(1<<14),	(1<<14)/2,	(1<<14)/3,	(1<<14)/4,	(1<<14)/5,	(1<<14)/6,	(1<<14)/7};struct snd snd;#define RATE (snd.rate)#define WAVE (snd.wave) /* ram.hi+0x30 */#define S1 (snd.ch[0])#define S2 (snd.ch[1])#define S3 (snd.ch[2])#define S4 (snd.ch[3])static void s1_freq_d(int d){	if (RATE > (d<<4)) S1.freq = 0;	else S1.freq = (RATE << 17)/d;}static void s1_freq(){
	int d = 2048 - (((R_NR14&7)<<8) + R_NR13);
	if (RATE > (d<<4)) S1.freq = 0;
	else S1.freq = (RATE << 17)/d;}static void s2_freq(){	int d = 2048 - (((R_NR24&7)<<8) + R_NR23);	if (RATE > (d<<4)) S2.freq = 0;	else S2.freq = (RATE << 17)/d;}static void s3_freq(){	int d = 2048 - (((R_NR34&7)<<8) + R_NR33);	if (RATE > (d<<3)) S3.freq = 0;	else S3.freq = (RATE << 21)/d;}static void s4_freq(){	S4.freq = (freqtab[R_NR43&7] >> (R_NR43 >> 4)) * RATE;	if (S4.freq >> 18) S4.freq = 1<<18;}void sound_dirty(){
	S1.swlen = ((R_NR10>>4) & 7) << 14;	S1.len = (64-(R_NR11&63)) << 13;	S1.envol = R_NR12 >> 4;	S1.endir = (R_NR12>>3) & 1;	S1.endir |= S1.endir - 1;	S1.enlen = (R_NR12 & 7) << 15;
	S1.mixr = (R_NR51 & 1);
	S1.mixl = (R_NR51 & 16) >> 4;
	S1.type = R_NR11>>6;
	S1.hold = R_NR14 & 64;
	S1.swshift = (R_NR10 & 7);
	S1.swdir = (R_NR10 & 8);	s1_freq();	S2.len = (64-(R_NR21&63)) << 13;	S2.envol = R_NR22 >> 4;	S2.endir = (R_NR22>>3) & 1;	S2.endir |= S2.endir - 1;	S2.enlen = (R_NR22 & 7) << 15;
	S2.mixr = (R_NR51 & 2) >> 1;
	S2.mixl = (R_NR51 & 32) >> 5;
	S2.type = R_NR21>>6;
	S2.hold = (R_NR24 & 64);	s2_freq();	S3.len = (256-R_NR31) << 20;
	S3.mixr = (R_NR51 & 4) >> 2;
	S3.mixl = (R_NR51 & 64) >> 6;
	S3.hold = (R_NR34 & 64);
	S3.endir = (R_NR32 & 96);
	S3.envol = (3 - ((R_NR32>>5)&3));	s3_freq();	S4.len = (64-(R_NR41&63)) << 13;	S4.envol = R_NR42 >> 4;	S4.endir = (R_NR42>>3) & 1;	S4.endir |= S4.endir - 1;	S4.enlen = (R_NR42 & 7) << 15;
	S4.mixr = (R_NR51 & 8) >> 3;
	S4.mixl = (R_NR51 & 128) >> 7;
	S4.hold = (R_NR44 & 64);	s4_freq();

	snd.master_voll = (R_NR50 & 0x07);
	snd.master_volr = ((R_NR50 & 0x70)>>4);}void sound_off(){	memset(&S1, 0, sizeof S1);	memset(&S2, 0, sizeof S2);	memset(&S3, 0, sizeof S3);	memset(&S4, 0, sizeof S4);	R_NR10 = 0x80;	R_NR11 = 0xBF;	R_NR12 = 0xF3;	R_NR14 = 0xBF;	R_NR21 = 0x3F;	R_NR22 = 0x00;	R_NR24 = 0xBF;	R_NR30 = 0x7F;	R_NR31 = 0xFF;	R_NR32 = 0x9F;	R_NR33 = 0xBF;	R_NR41 = 0xFF;	R_NR42 = 0x00;	R_NR43 = 0x00;	R_NR44 = 0xBF;	R_NR50 = 0x77;	R_NR51 = 0xF3;	R_NR52 = 0xF1;	sound_dirty();}void sound_reset(){	memset(&snd, 0, sizeof snd);	if (pcm.hz) snd.rate = (1<<21) / pcm.hz;	else snd.rate = 0;	memcpy(WAVE, hw.cgb ? cgbwave : dmgwave, 16);	memcpy(ram.hi+0x30, WAVE, 16);	sound_off();}void sound_mix(){	int s, l, r, f;	if (!RATE || cpu.snd < RATE) return;	for (; cpu.snd >= RATE; cpu.snd -= RATE)	{		l = r = 0;		if (S1.on)		{			s = sqwave[S1.type][(S1.pos>>18)&7] & S1.envol;			S1.pos += S1.freq;			if (S1.hold && ((S1.cnt += RATE) >= S1.len))				S1.on = 0;			if (S1.enlen && (S1.encnt += RATE) >= S1.enlen)			{				S1.encnt -= S1.enlen;				S1.envol += S1.endir;				if (S1.envol < 0) S1.envol = 0;				if (S1.envol > 15) S1.envol = 15;			}			if (S1.swlen && (S1.swcnt += RATE) >= S1.swlen)			{				S1.swcnt -= S1.swlen;
				if (S1.swshift) 
				{
					f = S1.swfreq;					if (S1.swdir) f -= (f >> S1.swshift);					else f += (f >> S1.swshift);
					if (f > 2047) 
						S1.on = 0;
					else
					{
						S1.swfreq = f;
						R_NR13 = f;
						R_NR14 = (R_NR14 & 0xF8) | (f>>8);
						s1_freq_d(2048 - f);

						S1.hold = R_NR14 & 64;
					}
				}			}			s <<= 2;			if (S1.mixr) r += s;			if (S1.mixl) l += s;		}				if (S2.on)		{			s = sqwave[S2.type][(S2.pos>>18)&7] & S2.envol;			S2.pos += S2.freq;			if (S2.hold && ((S2.cnt += RATE) >= S2.len))				S2.on = 0;			if (S2.enlen && (S2.encnt += RATE) >= S2.enlen)			{				S2.encnt -= S2.enlen;				S2.envol += S2.endir;				if (S2.envol < 0) S2.envol = 0;				if (S2.envol > 15) S2.envol = 15;			}			s <<= 2;			if (S2.mixr) r += s;			if (S2.mixl) l += s;		}				if (S3.on)		{			s = WAVE[(S3.pos>>22) & 15];			if (S3.pos & (1<<21)) s &= 15;			else s >>= 4;			s -= 8;			S3.pos += S3.freq;			if (S3.hold && ((S3.cnt += RATE) >= S3.len))				S3.on = 0;
			if (S3.endir)
				s <<= S3.envol;			else
				s = 0;			if (S3.mixr) r += s;			if (S3.mixl) l += s;		}		if (S4.on)		{			if (R_NR43 & 8) s = 1 & (noise7[				(S4.pos>>20)&15] >> (7-((S4.pos>>17)&7)));			else s = 1 & (noise15[				(S4.pos>>20)&4095] >> (7-((S4.pos>>17)&7)));			s = (-s) & S4.envol;			S4.pos += S4.freq;			if (S4.hold && ((S4.cnt += RATE) >= S4.len))				S4.on = 0;			if (S4.enlen && (S4.encnt += RATE) >= S4.enlen)			{				S4.encnt -= S4.enlen;				S4.envol += S4.endir;				if (S4.envol < 0) S4.envol = 0;				if (S4.envol > 15) S4.envol = 15;			}			s += s << 1;			if (S4.mixr) r += s;			if (S4.mixl) l += s;		}	
		l *= snd.master_voll;
		r *= snd.master_volr;
		l += (snd.master_voll - 3) << 4;
		r += (snd.master_volr - 3) << 4;
				
		if (pcm.buf)		{			if (pcm.pos >= pcm.len)				pcm_submit();			if (pcm_get_16bits()) 			{				short* sample = pcm.buf;				l <<= 4;				r <<= 4;				if (pcm.stereo)				{					if (l > 32767) l = 32767;					else if (l < -32768) l = -32768;					if (r > 32767) r = 32767;					else if (r < -32768) r = -32768;					sample[pcm.pos++] = l;					sample[pcm.pos++] = r;				}				else 				{					l += r;					l >>= 1;					if (l > 32767) l = 32767;					else if (l < -32768) l = -32768;					sample[pcm.pos++] = l;				}			}			else			{				l >>= 4;				r >>= 4;				if (pcm.stereo)				{					if (l > 127) l = 127;					else if (l < -128) l = -128;					if (r > 127) r = 127;					else if (r < -128) r = -128;					pcm.buf[pcm.pos++] = l + 128;					pcm.buf[pcm.pos++] = r + 128;				}				else 				{					l += r;					l >>= 1;					if (l > 127) l = 127;					else if (l < -128) l = -128;					pcm.buf[pcm.pos++] = l+128;				}			}		}	}	R_NR52 = (R_NR52&0xf0) | S1.on | (S2.on<<1) | (S3.on<<2) | (S4.on<<3);}byte sound_read(byte r){	sound_mix();	return REG(r);}
void s1_init(){
	S1.swcnt = 0;	S1.swfreq = ((R_NR14&7)<<8) + R_NR13;	S1.envol = R_NR12 >> 4;	S1.endir = (R_NR12>>3) & 1;	S1.endir |= S1.endir - 1;	S1.enlen = (R_NR12 & 7) << 15;	if (!S1.on) S1.pos = 0;	S1.on = 1;	S1.cnt = 0;	S1.encnt = 0;}void s2_init(){	S2.envol = R_NR22 >> 4;	S2.endir = (R_NR22>>3) & 1;	S2.endir |= S2.endir - 1;	S2.enlen = (R_NR22 & 7) << 15;	if (!S2.on) S2.pos = 0;	S2.on = 1;	S2.cnt = 0;	S2.encnt = 0;}void s3_init(){	if (!S3.on) S3.pos = 0;	S3.cnt = 0;
	S3.on = 1;	//for (i = 0; i < 16; i++)	//	ram.hi[i+0x30] = 0x13 ^ ram.hi[i+0x31];}void s4_init(){	S4.envol = R_NR42 >> 4;	S4.endir = (R_NR42>>3) & 1;	S4.endir |= S4.endir - 1;	S4.enlen = (R_NR42 & 7) << 15;	S4.on = 1;	S4.pos = 0;	S4.cnt = 0;	S4.encnt = 0;}void sound_write(byte r, byte b){
	sound_mix();	switch (r)	{	case RI_NR10:		R_NR10 = b;		S1.swlen = ((R_NR10>>4) & 7) << 14;		S1.swfreq = ((R_NR14&7)<<8) + R_NR13;
		S1.swshift = (R_NR10 & 7);
		S1.swdir = (R_NR10 & 8);		break;	case RI_NR11:		R_NR11 = b;		S1.len = (64-(R_NR11&63)) << 13;
		S1.type = R_NR11>>6;		break;	case RI_NR12:		R_NR12 = b;		S1.envol = R_NR12 >> 4;		S1.endir = (R_NR12>>3) & 1;		S1.endir |= S1.endir - 1;		S1.enlen = (R_NR12 & 7) << 15;		break;	case RI_NR13:		R_NR13 = b;		s1_freq();		break;	case RI_NR14:		R_NR14 = b;
		S1.hold = R_NR14 & 64;		s1_freq();		if (b & 128) s1_init();		break;	case RI_NR21:		R_NR21 = b;		S2.len = (64-(R_NR21&63)) << 13;
		S2.type = R_NR21>>6;		break;	case RI_NR22:		R_NR22 = b;		S2.envol = R_NR22 >> 4;		S2.endir = (R_NR22>>3) & 1;		S2.endir |= S2.endir - 1;		S2.enlen = (R_NR22 & 7) << 15;		break;	case RI_NR23:		R_NR23 = b;		s2_freq();		break;	case RI_NR24:		R_NR24 = b;
		S2.hold = (R_NR24 & 64);		s2_freq();		if (b & 128) s2_init();		break;	case RI_NR30:		R_NR30 = b;		if (!(b & 128)) S3.on = 0;		break;	case RI_NR31:		R_NR31 = b;		S3.len = (256-R_NR31) << 13;		break;	case RI_NR32:		R_NR32 = b;
		S3.endir = (R_NR32 & 96);
		S3.envol = (3 - ((R_NR32>>5)&3));		break;	case RI_NR33:		R_NR33 = b;		s3_freq();		break;	case RI_NR34:		R_NR34 = b;
		S3.hold = (R_NR34 & 64);		s3_freq();		if ((b & 128) && (R_NR30 & 0x80)) 
			s3_init();		break;	case RI_NR41:		R_NR41 = b;		S4.len = (64-(R_NR41&63)) << 13;		break;	case RI_NR42:		R_NR42 = b;		S4.envol = R_NR42 >> 4;		S4.endir = (R_NR42>>3) & 1;		S4.endir |= S4.endir - 1;		S4.enlen = (R_NR42 & 7) << 15;		break;	case RI_NR43:		R_NR43 = b;		s4_freq();		break;	case RI_NR44:		R_NR44 = b;
		S4.hold = (R_NR44 & 64);		if (b & 128) s4_init();		break;	case RI_NR50:		R_NR50 = b;
		snd.master_voll = (R_NR50 & 0x07);
		snd.master_volr = ((R_NR50 & 0x70)>>4);		break;	case RI_NR51:		R_NR51 = b;
		S1.mixr = (R_NR51 & 1);
		S1.mixl = (R_NR51 & 16) >> 4;
		S2.mixr = (R_NR51 & 2) >> 1;
		S2.mixl = (R_NR51 & 32) >> 5;
		S3.mixr = (R_NR51 & 4) >> 2;
		S3.mixl = (R_NR51 & 64) >> 6;
		S4.mixr = (R_NR51 & 8) >> 3;
		S4.mixl = (R_NR51 & 128) >> 7;		break;	case RI_NR52:		R_NR52 = b;		if (!(R_NR52 & 128))			sound_off();		break;
	case 0x30:
	case 0x31:
	case 0x32:
	case 0x33:
	case 0x34:
	case 0x35:
	case 0x36:
	case 0x37:
	case 0x38:
	case 0x39:
	case 0x3A:
	case 0x3B:
	case 0x3C:
	case 0x3D:
	case 0x3E:
	case 0x3F:
		WAVE[r-0x30] = ram.hi[r] = b;
		break;
	default:
		ram.hi[r] = b;	}}

⌨️ 快捷键说明

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