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

📄 soundux.cpp

📁 著名SFC模拟器Snes9x的源代码。
💻 CPP
📖 第 1 页 / 共 4 页
字号:
		{		    if (Settings.InterpolatedSound && freq < FIXED_POINT && !mod)		    {			ch->interpolate = ((ch->next_sample - ch->sample) * 					   (long) freq) / (long) FIXED_POINT;			ch->sample = (int16) (ch->sample + (((ch->next_sample - ch->sample) * 					   (long) (ch->count)) / (long) FIXED_POINT));		    }		  		    else			ch->interpolate = 0;		}		else		{		    for (;VL > 0; VL--)			if ((so.noise_gen <<= 1) & 0x80000000L)			    so.noise_gen ^= 0x0040001L;		    ch->sample = (so.noise_gen << 17) >> 17;		    ch->interpolate = 0;		}		VL = (ch->sample * ch-> left_vol_level) / 128;		VR = (ch->sample * ch->right_vol_level) / 128;            }	    else	    {		if (ch->interpolate)		{		    int32 s = (int32) ch->sample + ch->interpolate;		    		    CLIP16(s);		    ch->sample = (int16) s;		    VL = (ch->sample * ch-> left_vol_level) / 128;		    VR = (ch->sample * ch->right_vol_level) / 128;		}	    }	    if (pitch_mod & (1 << (J + 1)))		wave [I / 2] = ch->sample * ch->envx;	    MixBuffer [I      ^ Settings.ReverseStereo] += VL;	    MixBuffer [I + (1 ^ Settings.ReverseStereo)] += VR;	    ch->echo_buf_ptr [I      ^ Settings.ReverseStereo] += VL;	    ch->echo_buf_ptr [I + (1 ^ Settings.ReverseStereo)] += VR;        }stereo_exit: ;    }}#ifdef __DJGPPEND_OF_FUNCTION(MixStereo);#endifvoid MixMono (int sample_count){#if defined(TARGET_OS_MAC) && TARGET_OS_MAC    static int wave[SOUND_BUFFER_SIZE];#else    int wave[SOUND_BUFFER_SIZE];#endif    int pitch_mod = SoundData.pitch_mod & (~APU.DSP[APU_NON]);    for (uint32 J = 0; J < NUM_CHANNELS; J++)     {	Channel *ch = &SoundData.channels[J];	unsigned long freq0 = ch->frequency;	if (ch->state == SOUND_SILENT || !(so.sound_switch & (1 << J)))	    continue;//	freq0 = (unsigned long) ((double) freq0 * 0.985);	bool8 mod = pitch_mod & (1 << J);	if (ch->needs_decode) 	{	    DecodeBlock(ch);	    ch->needs_decode = FALSE;	    ch->sample = ch->block[0];	    ch->sample_pointer = freq0 >> FIXED_POINT_SHIFT;	    if (ch->sample_pointer == 0)		ch->sample_pointer = 1;	    if (ch->sample_pointer > SOUND_DECODE_LENGTH)		ch->sample_pointer = SOUND_DECODE_LENGTH - 1;	    ch->next_sample = ch->block[ch->sample_pointer];	    ch->interpolate = 0;	    if (Settings.InterpolatedSound && freq0 < FIXED_POINT && !mod)		ch->interpolate = ((ch->next_sample - ch->sample) * 				   (long) freq0) / (long) FIXED_POINT;	}	int32 V = (ch->sample * ch->left_vol_level) / 128;	for (uint32 I = 0; I < (uint32) sample_count; I++)	{	    unsigned long freq = freq0;	    if (mod)		freq = PITCH_MOD(freq, wave [I]);	    ch->env_error += ch->erate;	    if (ch->env_error >= FIXED_POINT) 	    {		uint32 step = ch->env_error >> FIXED_POINT_SHIFT;		switch (ch->state)		{		case SOUND_ATTACK:		    ch->env_error &= FIXED_POINT_REMAINDER;		    ch->envx += step << 1;		    ch->envxx = ch->envx << ENVX_SHIFT;		    if (ch->envx >= 126)		    {			ch->envx = 127;			ch->envxx = 127 << ENVX_SHIFT;			ch->state = SOUND_DECAY;			if (ch->sustain_level != 8) 			{			    S9xSetEnvRate (ch, ch->decay_rate, -1,						(MAX_ENVELOPE_HEIGHT * ch->sustain_level)						>> 3);			    break;			}			ch->state = SOUND_SUSTAIN;			S9xSetEnvRate (ch, ch->sustain_rate, -1, 0);		    }		    break;				case SOUND_DECAY:		    while (ch->env_error >= FIXED_POINT)		    {			ch->envxx = (ch->envxx >> 8) * 255;			ch->env_error -= FIXED_POINT;		    }		    ch->envx = ch->envxx >> ENVX_SHIFT;		    if (ch->envx <= ch->envx_target)		    {			if (ch->envx <= 0)			{			    S9xAPUSetEndOfSample (J, ch);			    goto mono_exit;			}			ch->state = SOUND_SUSTAIN;			S9xSetEnvRate (ch, ch->sustain_rate, -1, 0);		    }		    break;		case SOUND_SUSTAIN:		    while (ch->env_error >= FIXED_POINT)		    {			ch->envxx = (ch->envxx >> 8) * 255;			ch->env_error -= FIXED_POINT;		    }		    ch->envx = ch->envxx >> ENVX_SHIFT;		    if (ch->envx <= 0)		    {			S9xAPUSetEndOfSample (J, ch);			goto mono_exit;		    }		    break;		    		case SOUND_RELEASE:		    while (ch->env_error >= FIXED_POINT)		    {			ch->envxx -= (MAX_ENVELOPE_HEIGHT << ENVX_SHIFT) / 256;			ch->env_error -= FIXED_POINT;		    }		    ch->envx = ch->envxx >> ENVX_SHIFT;		    if (ch->envx <= 0)		    {			S9xAPUSetEndOfSample (J, ch);			goto mono_exit;		    }		    break;				case SOUND_INCREASE_LINEAR:		    ch->env_error &= FIXED_POINT_REMAINDER;		    ch->envx += step << 1;		    ch->envxx = ch->envx << ENVX_SHIFT;		    if (ch->envx >= 126)		    {			ch->envx = 127;			ch->envxx = 127 << ENVX_SHIFT;			ch->state = SOUND_GAIN;			ch->mode = MODE_GAIN;			S9xSetEnvRate (ch, 0, -1, 0);		    }		    break;		case SOUND_INCREASE_BENT_LINE:		    if (ch->envx >= (MAX_ENVELOPE_HEIGHT * 3) / 4)		    {			while (ch->env_error >= FIXED_POINT)			{			    ch->envxx += (MAX_ENVELOPE_HEIGHT << ENVX_SHIFT) / 256;			    ch->env_error -= FIXED_POINT;			}			ch->envx = ch->envxx >> ENVX_SHIFT;		    }		    else		    {			ch->env_error &= FIXED_POINT_REMAINDER;			ch->envx += step << 1;			ch->envxx = ch->envx << ENVX_SHIFT;		    }		    if (ch->envx >= 126)		    {			ch->envx = 127;			ch->envxx = 127 << ENVX_SHIFT;			ch->state = SOUND_GAIN;			ch->mode = MODE_GAIN;			S9xSetEnvRate (ch, 0, -1, 0);		    }		    break;		case SOUND_DECREASE_LINEAR:		    ch->env_error &= FIXED_POINT_REMAINDER;		    ch->envx -= step << 1;		    ch->envxx = ch->envx << ENVX_SHIFT;		    if (ch->envx <= 0)		    {			S9xAPUSetEndOfSample (J, ch);			goto mono_exit;		    }		    break;		case SOUND_DECREASE_EXPONENTIAL:		    while (ch->env_error >= FIXED_POINT)		    {			ch->envxx = (ch->envxx >> 8) * 255;			ch->env_error -= FIXED_POINT;		    }		    ch->envx = ch->envxx >> ENVX_SHIFT;		    if (ch->envx <= 0)		    {			S9xAPUSetEndOfSample (J, ch);			goto mono_exit;		    }		    break;				case SOUND_GAIN:		    S9xSetEnvRate (ch, 0, -1, 0);		    break;		}		ch->left_vol_level = (ch->envx * ch->volume_left) / 128;		V = (ch->sample * ch->left_vol_level) / 128;	    }	    ch->count += freq;	    if (ch->count >= FIXED_POINT)	    {		V = ch->count >> FIXED_POINT_SHIFT;		ch->sample_pointer += V;		ch->count &= FIXED_POINT_REMAINDER;		ch->sample = ch->next_sample;		if (ch->sample_pointer >= SOUND_DECODE_LENGTH)		{		    if (JUST_PLAYED_LAST_SAMPLE(ch))		    {			S9xAPUSetEndOfSample (J, ch);			goto mono_exit;		    }		    do		    {			ch->sample_pointer -= SOUND_DECODE_LENGTH;			if (ch->last_block)			{			    if (!ch->loop)			    {				ch->sample_pointer = LAST_SAMPLE;				ch->next_sample = ch->sample;				break;			    }			    else			    {				ch->last_block = FALSE;				uint8 *dir = S9xGetSampleAddress (ch->sample_number);				ch->block_pointer = READ_WORD(dir + 2);				S9xAPUSetEndX (J);			    }			}			DecodeBlock (ch);		    } while (ch->sample_pointer >= SOUND_DECODE_LENGTH);		    if (!JUST_PLAYED_LAST_SAMPLE (ch))			ch->next_sample = ch->block [ch->sample_pointer];		}		else		    ch->next_sample = ch->block [ch->sample_pointer];		if (ch->type == SOUND_SAMPLE)		{		    if (Settings.InterpolatedSound && freq < FIXED_POINT && !mod)		    {			ch->interpolate = ((ch->next_sample - ch->sample) * 					   (long) freq) / (long) FIXED_POINT;			ch->sample = (int16) (ch->sample + (((ch->next_sample - ch->sample) * 					   (long) (ch->count)) / (long) FIXED_POINT));		    }		  		    else			ch->interpolate = 0;		}		else		{		    for (;V > 0; V--)			if ((so.noise_gen <<= 1) & 0x80000000L)			    so.noise_gen ^= 0x0040001L;		    ch->sample = (so.noise_gen << 17) >> 17;		    ch->interpolate = 0;		}		V = (ch->sample * ch-> left_vol_level) / 128;            }	    else	    {		if (ch->interpolate)		{		    int32 s = (int32) ch->sample + ch->interpolate;		    CLIP16(s);		    ch->sample = (int16) s;		    V = (ch->sample * ch-> left_vol_level) / 128;		}	    }	    MixBuffer [I] += V;	    ch->echo_buf_ptr [I] += V;	    if (pitch_mod & (1 << (J + 1)))		wave [I] = ch->sample * ch->envx;        }mono_exit: ;    }}#ifdef __DJGPPEND_OF_FUNCTION(MixMono);#endif#ifdef __sunextern uint8 int2ulaw (int);#endif// For backwards compatibility with older port specific codevoid S9xMixSamples (uint8 *buffer, int sample_count){    S9xMixSamplesO (buffer, sample_count, 0);}#ifdef __DJGPPEND_OF_FUNCTION(S9xMixSamples);#endifvoid S9xMixSamplesO (uint8 *buffer, int sample_count, int byte_offset){    int J;    int I;    if (!so.mute_sound)    {	memset (MixBuffer, 0, sample_count * sizeof (MixBuffer [0]));	if (SoundData.echo_enable)	    memset (EchoBuffer, 0, sample_count * sizeof (EchoBuffer [0]));	if (so.stereo)	    MixStereo (sample_count);	else	    MixMono (sample_count);    }    /* Mix and convert waveforms */    if (so.sixteen_bit)    {	int byte_count = sample_count << 1;		// 16-bit sound	if (so.mute_sound)	{            memset (buffer + byte_offset, 0, byte_count);	}	else	{	    int O = byte_offset >> 1;	    if (SoundData.echo_enable && SoundData.echo_buffer_size)	    {		if (so.stereo)		{		    // 16-bit stereo sound with echo enabled ...		    if (SoundData.no_filter)		    {			// ... but no filter defined.			for (J = 0; J < sample_count; J++)			{			    int E = Echo [SoundData.echo_ptr];			    Echo [SoundData.echo_ptr] = (E * SoundData.echo_feedback) / 128 +							EchoBuffer [J];			    if ((SoundData.echo_ptr += 1) >= SoundData.echo_buffer_size)				SoundData.echo_ptr = 0;			    I = (MixBuffer [J] * 				 SoundData.master_volume [J & 1] +				 E * SoundData.echo_volume [J & 1]) / VOL_DIV16;			    CLIP16(I);			    ((signed short *) buffer)[J + O] = I;			}		    }		    else		    {			// ... with filter defined.			for (J = 0; J < sample_count; J++)			{			    int E = Echo [SoundData.echo_ptr];			    Loop [(Z - 0) & 15] = E;			    E =  E                    * FilterTaps [0];			    E += Loop [(Z -  2) & 15] * FilterTaps [1];			    E += Loop [(Z -  4) & 15] * FilterTaps [2];			    E += Loop [(Z -  6) & 15] * FilterTaps [3];			    E += Loop [(Z -  8) & 15] * FilterTaps [4];			    E += Loop [(Z - 10) & 15] * FilterTaps [5];			    E += Loop [(Z - 12) & 15] * FilterTaps [6];			    E += Loop [(Z - 14) & 15] * FilterTaps [7];			    E /= 128;			    Z++;			    Echo [SoundData.echo_ptr] = (E * SoundData.echo_feedback) / 128 +							EchoBuffer [J];			    if ((SoundData.echo_ptr += 1) >= SoundData.echo_buffer_size)				SoundData.echo_ptr = 0;			    I = (MixBuffer [J] * 				 SoundData.master_volume [J & 1] +				 E * SoundData.echo_volume [J & 1]) / VOL_DIV16;			    CLIP16(I);			    ((signed short *) buffer)[J + O] = I;			}		    }		}		else		{		    // 16-bit mono sound with echo enabled...		    if (SoundData.no_filter)		    {			// ... no filter defined			for (J = 0; J < sample_count; J++)			{			    int E = Echo [SoundData.echo_ptr];			    Echo [SoundData.echo_ptr] = (E * SoundData.echo_feedback) / 128 +

⌨️ 快捷键说明

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