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

📄 soundux.cpp

📁 著名SFC模拟器Snes9x的源代码。
💻 CPP
📖 第 1 页 / 共 4 页
字号:
    signed char *compressed = (signed char *) &IAPU.RAM [ch->block_pointer];    unsigned char filter = *compressed;    if ((ch->last_block = filter & 1))	ch->loop = (filter & 2) != 0;#if (defined (__linux__) && (defined (__i386__) || defined (__i486__) ||\     defined (__i586__))) || defined (__WIN32__)    int16 *raw = ch->block = ch->decoded;    DecodeBlockAsm (compressed, raw, &ch->previous [0], &ch->previous [1]);#else    int32 out;    unsigned char shift;    signed char sample1, sample2;    unsigned int i;    // If enabled, results in 'tick' sound on some samples that repeat by    // re-using part of the original sample but generate a slightly different    // waveform.    if (!Settings.DisableSampleCaching &&	memcmp ((uint8 *) compressed, &IAPU.ShadowRAM [ch->block_pointer], 9) == 0)    {	ch->block = (signed short *) (IAPU.CachedSamples + (ch->block_pointer << 2));	ch->previous [0] = ch->block [15];	ch->previous [1] = ch->block [14];    }    else    {	if (!Settings.DisableSampleCaching)	    memcpy (&IAPU.ShadowRAM [ch->block_pointer], (uint8 *) compressed, 9);	compressed++;	signed short *raw = ch->block = ch->decoded;		int32 prev0 = ch->previous [0];	int32 prev1 = ch->previous [1];	shift = filter >> 4;	switch ((filter >> 2) & 3)	{        case 0:	    for (i = 8; i != 0; i--)	    {		sample1 = *compressed++;		sample2 = sample1 << 4;		sample2 >>= 4;		sample1 >>= 4;		*raw++ = ((int32) sample1 << shift);		*raw++ = ((int32) sample2 << shift);	    }	    prev1 = *(raw - 2);	    prev0 = *(raw - 1);	    break;	case 1:	    for (i = 8; i != 0; i--)	    {		sample1 = *compressed++;		sample2 = sample1 << 4;		sample2 >>= 4;		sample1 >>= 4;		prev0 = (int16) prev0;		*raw++ = prev1 = ((int32) sample1 << shift) + prev0 - (prev0 >> 4);		prev1 = (int16) prev1;		*raw++ = prev0 = ((int32) sample2 << shift) + prev1 - (prev1 >> 4);	    }	    break;        case 2:	    for (i = 8; i != 0; i--)	    {		sample1 = *compressed++;		sample2 = sample1 << 4;		sample2 >>= 4;		sample1 >>= 4;				out = (sample1 << shift) - prev1 + (prev1 >> 4);		prev1 = (int16) prev0;		*raw++ = prev0 = out + (prev0 << 1) - (prev0 >> 5) - 				 (prev0 >> 4);		out = (sample2 << shift) - prev1 + (prev1 >> 4);		prev1 = (int16) prev0;		*raw++ = prev0 = out + (prev0 << 1) - (prev0 >> 5) -			         (prev0 >> 4);	    }	    break;	case 3:	    for (i = 8; i != 0; i--)	    {		sample1 = *compressed++;		sample2 = sample1 << 4;		sample2 >>= 4;		sample1 >>= 4;		out = (sample1 << shift);		out = out - prev1 + (prev1 >> 3) + (prev1 >> 4);		prev1 = (int16) prev0;		*raw++ = prev0 = out + (prev0 << 1) - (prev0 >> 3) - 			         (prev0 >> 4) - (prev1 >> 6);		out = (sample2 << shift);		out = out - prev1 + (prev1 >> 3) + (prev1 >> 4);		prev1 = (int16) prev0;		*raw++ = prev0 = out + (prev0 << 1) - (prev0 >> 3) - 			         (prev0 >> 4) - (prev1 >> 6);	    }	    break;	}	ch->previous [0] = prev0;	ch->previous [1] = prev1;	if (!Settings.DisableSampleCaching)	{	    memcpy (IAPU.CachedSamples + (ch->block_pointer << 2),		    (uint8 *) ch->decoded, 32);	}    }#endif    ch->block_pointer += 9;}void DecodeBlock (Channel *ch){    int32 out;    unsigned char filter;    unsigned char shift;    signed char sample1, sample2;    unsigned char i;    if (Settings.AltSampleDecode)    {        AltDecodeBlock (ch);        return;    }    if (ch->block_pointer > 0x10000 - 9)    {	ch->last_block = TRUE;	ch->loop = FALSE;	ch->block = ch->decoded;	return;    }    signed char *compressed = (signed char *) &IAPU.RAM [ch->block_pointer];    filter = *compressed;    if ((ch->last_block = filter & 1))	ch->loop = (filter & 2) != 0;    // If enabled, results in 'tick' sound on some samples that repeat by    // re-using part of the original sample but generate a slightly different    // waveform.    if (!Settings.DisableSampleCaching &&	memcmp ((uint8 *) compressed, &IAPU.ShadowRAM [ch->block_pointer], 9) == 0)    {	ch->block = (signed short *) (IAPU.CachedSamples + (ch->block_pointer << 2));	ch->previous [0] = ch->block [15];	ch->previous [1] = ch->block [14];    }    else    {	if (!Settings.DisableSampleCaching)	    memcpy (&IAPU.ShadowRAM [ch->block_pointer], (uint8 *) compressed, 9);	compressed++;	signed short *raw = ch->block = ch->decoded;	shift = filter >> 4;	filter = ((filter >> 2) & 3);	int32 prev0 = ch->previous [0];	int32 prev1 = ch->previous [1];	int32 f0 = FilterValues[filter][0];	int32 f1 = FilterValues[filter][1];	for (i = 8; i != 0; i--)	{	    sample1 = *compressed++;	    sample2 = sample1 << 4;	    //Sample 2 = Bottom Nibble, Sign Extended.	    sample2 >>= 4;	    //Sample 1 = Top Nibble, shifted down and Sign Extended.	    sample1 >>= 4;	    out = (sample1 << shift);	    out += (prev0 * f0 + prev1 * f1) / 256;	    CLIP16 (out);	    prev1 = prev0;	    prev0 = out;	    *raw++ = (signed short) out;	    out = (sample2 << shift);	    out += (prev0 * f0 + prev1 * f1) / 256;	    CLIP16 (out);	    prev1 = prev0;	    prev0 = out;	    *raw++ = (signed short) out;	}	ch->previous [0] = prev0;	ch->previous [1] = prev1;	if (!Settings.DisableSampleCaching)	{	    memcpy (IAPU.CachedSamples + (ch->block_pointer << 2),		    (uint8 *) ch->decoded, 32);	}    }    ch->block_pointer += 9;}void MixStereo (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++)     {	int32 VL, VR;	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;	}	VL = (ch->sample * ch-> left_vol_level) / 128;	VR = (ch->sample * ch->right_vol_level) / 128;	for (uint32 I = 0; I < (uint32) sample_count; I += 2)	{	    unsigned long freq = freq0;	    if (mod)		freq = PITCH_MOD(freq, wave [I / 2]);	    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 stereo_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 stereo_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 stereo_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 stereo_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 stereo_exit;		    }		    break;				case SOUND_GAIN:		    S9xSetEnvRate (ch, 0, -1, 0);		    break;		}		ch-> left_vol_level = (ch->envx * ch->volume_left) / 128;		ch->right_vol_level = (ch->envx * ch->volume_right) / 128;		VL = (ch->sample * ch-> left_vol_level) / 128;		VR = (ch->sample * ch->right_vol_level) / 128;	    }	    ch->count += freq;	    if (ch->count >= FIXED_POINT)	    {		VL = ch->count >> FIXED_POINT_SHIFT;		ch->sample_pointer += VL;		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 stereo_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			    {				S9xAPUSetEndX (J);				ch->last_block = FALSE;				uint8 *dir = S9xGetSampleAddress (ch->sample_number);				ch->block_pointer = READ_WORD(dir + 2);			    }			}			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)

⌨️ 快捷键说明

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