📄 soundux.cpp
字号:
{ 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 + -