📄 soundux.cpp
字号:
EchoBuffer [J]; if ((SoundData.echo_ptr += 1) >= SoundData.echo_buffer_size) SoundData.echo_ptr = 0; I = (MixBuffer [J] * SoundData.master_volume [0] + E * SoundData.echo_volume [0]) / 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) & 7] = E; E = E * FilterTaps [0]; E += Loop [(Z - 1) & 7] * FilterTaps [1]; E += Loop [(Z - 2) & 7] * FilterTaps [2]; E += Loop [(Z - 3) & 7] * FilterTaps [3]; E += Loop [(Z - 4) & 7] * FilterTaps [4]; E += Loop [(Z - 5) & 7] * FilterTaps [5]; E += Loop [(Z - 6) & 7] * FilterTaps [6]; E += Loop [(Z - 7) & 7] * 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 [0] + E * SoundData.echo_volume [0]) / VOL_DIV16; CLIP16(I); ((signed short *) buffer)[J + O] = I; } } } } else { // 16-bit mono or stereo sound, no echo for (J = 0; J < sample_count; J++) { I = (MixBuffer [J] * SoundData.master_volume [J & 1]) / VOL_DIV16; CLIP16(I); ((signed short *) buffer)[J + O] = I; } } } } else { int O = byte_offset; // 8-bit sound if (so.mute_sound) { memset (buffer + O, 128, sample_count); } else#ifdef __sun if (so.encoded) { for (J = 0; J < sample_count; J++) { I = (MixBuffer [J] * SoundData.master_volume_left) / VOL_DIV16; CLIP16(I); buffer[J + O] = int2ulaw (I); } } else#endif { if (SoundData.echo_enable && SoundData.echo_buffer_size) { if (so.stereo) { // 8-bit stereo sound with echo enabled... if (SoundData.no_filter) { // ... but no filter 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_DIV8; CLIP8(I); buffer [J + O] = I + 128; } } else { // ... with filter 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_DIV8; CLIP8(I); buffer [J + O] = I + 128; } } } else { // 8-bit mono sound with echo enabled... if (SoundData.no_filter) { // ... but no filter. 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 [0] + E * SoundData.echo_volume [0]) / VOL_DIV8; CLIP8(I); buffer [J + O] = I + 128; } } else { // ... with filter. for (J = 0; J < sample_count; J++) { int E = Echo [SoundData.echo_ptr]; Loop [(Z - 0) & 7] = E; E = E * FilterTaps [0]; E += Loop [(Z - 1) & 7] * FilterTaps [1]; E += Loop [(Z - 2) & 7] * FilterTaps [2]; E += Loop [(Z - 3) & 7] * FilterTaps [3]; E += Loop [(Z - 4) & 7] * FilterTaps [4]; E += Loop [(Z - 5) & 7] * FilterTaps [5]; E += Loop [(Z - 6) & 7] * FilterTaps [6]; E += Loop [(Z - 7) & 7] * 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 [0] + E * SoundData.echo_volume [0]) / VOL_DIV8; CLIP8(I); buffer [J + O] = I + 128; } } } } else { // 8-bit mono or stereo sound, no echo for (J = 0; J < sample_count; J++) { I = (MixBuffer [J] * SoundData.master_volume [J & 1]) / VOL_DIV8; CLIP8(I); buffer [J + O] = I + 128; } } } }}#ifdef __DJGPPEND_OF_FUNCTION(S9xMixSamplesO);#endifvoid S9xResetSound (bool8 full){ for (int i = 0; i < 8; i++) { SoundData.channels[i].state = SOUND_SILENT; SoundData.channels[i].mode = MODE_NONE; SoundData.channels[i].type = SOUND_SAMPLE; SoundData.channels[i].volume_left = 0; SoundData.channels[i].volume_right = 0; SoundData.channels[i].hertz = 0; SoundData.channels[i].count = 0; SoundData.channels[i].loop = FALSE; SoundData.channels[i].envx_target = 0; SoundData.channels[i].env_error = 0; SoundData.channels[i].erate = 0; SoundData.channels[i].envx = 0; SoundData.channels[i].envxx = 0; SoundData.channels[i].left_vol_level = 0; SoundData.channels[i].right_vol_level = 0; SoundData.channels[i].direction = 0; SoundData.channels[i].attack_rate = 0; SoundData.channels[i].decay_rate = 0; SoundData.channels[i].sustain_rate = 0; SoundData.channels[i].release_rate = 0; SoundData.channels[i].sustain_level = 0; SoundData.echo_ptr = 0; SoundData.echo_feedback = 0; SoundData.echo_buffer_size = 1; } FilterTaps [0] = 127; FilterTaps [1] = 0; FilterTaps [2] = 0; FilterTaps [3] = 0; FilterTaps [4] = 0; FilterTaps [5] = 0; FilterTaps [6] = 0; FilterTaps [7] = 0; so.mute_sound = TRUE; so.noise_gen = 1; so.sound_switch = 255; so.samples_mixed_so_far = 0; so.play_position = 0; so.err_counter = 0; SoundData.master_volume_left = 127; SoundData.master_volume_right = 127; SoundData.master_volume [0] = SoundData.master_volume [1] = 127; if (so.playback_rate) so.err_rate = (uint32) (FIXED_POINT * SNES_SCANLINE_TIME / (1.0 / so.playback_rate)); else so.err_rate = 0; SoundData.no_filter = TRUE;}void S9xSetPlaybackRate (uint32 playback_rate){ so.playback_rate = playback_rate; so.err_rate = (uint32) (SNES_SCANLINE_TIME * FIXED_POINT / (1.0 / (double) so.playback_rate)); S9xSetEchoDelay (APU.DSP [APU_EDL] & 0xf); for (int i = 0; i < 8; i++) S9xSetSoundFrequency (i, SoundData.channels [i].hertz);}bool8 S9xInitSound (int mode, bool8 stereo, int buffer_size){ so.sound_fd = -1; so.sound_switch = 255; so.playback_rate = 0; so.buffer_size = 0; so.stereo = stereo; so.sixteen_bit = Settings.SixteenBitSound; so.encoded = FALSE; S9xResetSound (TRUE); if (!(mode & 7)) return (1); S9xSetSoundMute (TRUE); if (!S9xOpenSoundDevice (mode, stereo, buffer_size)) { S9xMessage (S9X_ERROR, S9X_SOUND_DEVICE_OPEN_FAILED, "Sound device open failed"); return (0); } return (1);}bool8 S9xSetSoundMode (int channel, int mode){ Channel *ch = &SoundData.channels[channel]; switch (mode) { case MODE_RELEASE: if (ch->mode != MODE_NONE) { ch->mode = MODE_RELEASE; return (TRUE); } break; case MODE_DECREASE_LINEAR: case MODE_DECREASE_EXPONENTIAL: case MODE_GAIN: if (ch->mode != MODE_RELEASE) { ch->mode = mode; if (ch->state != SOUND_SILENT) ch->state = mode; return (TRUE); } break; case MODE_INCREASE_LINEAR: case MODE_INCREASE_BENT_LINE: if (ch->mode != MODE_RELEASE) { ch->mode = mode; if (ch->state != SOUND_SILENT) ch->state = mode; return (TRUE); } break; case MODE_ADSR: if (ch->mode == MODE_NONE || ch->mode == MODE_ADSR) { ch->mode = mode; return (TRUE); } } return (FALSE);}void S9xSetSoundControl (int sound_switch){ so.sound_switch = sound_switch;}void S9xPlaySample (int channel){ Channel *ch = &SoundData.channels[channel]; ch->state = SOUND_SILENT; ch->mode = MODE_NONE; ch->envx = 0; ch->envxx = 0; S9xFixEnvelope (channel, APU.DSP [APU_GAIN + (channel << 4)], APU.DSP [APU_ADSR1 + (channel << 4)], APU.DSP [APU_ADSR2 + (channel << 4)]); ch->sample_number = APU.DSP [APU_SRCN + channel * 0x10]; if (APU.DSP [APU_NON] & (1 << channel)) ch->type = SOUND_NOISE; else ch->type = SOUND_SAMPLE; S9xSetSoundFrequency (channel, ch->hertz); ch->loop = FALSE; ch->needs_decode = TRUE; ch->last_block = FALSE; ch->previous [0] = ch->previous[1] = 0; uint8 *dir = S9xGetSampleAddress (ch->sample_number); ch->block_pointer = READ_WORD (dir); ch->sample_pointer = 0; ch->env_error = 0; ch->next_sample = 0; ch->interpolate = 0; switch (ch->mode) { case MODE_ADSR: if (ch->attack_rate == 0) { if (ch->decay_rate == 0 || ch->sustain_level == 8) { ch->state = SOUND_SUSTAIN; ch->envx = (MAX_ENVELOPE_HEIGHT * ch->sustain_level) >> 3; S9xSetEnvRate (ch, ch->sustain_rate, -1, 0); } else { ch->state = SOUND_DECAY; ch->envx = MAX_ENVELOPE_HEIGHT; S9xSetEnvRate (ch, ch->decay_rate, -1, (MAX_ENVELOPE_HEIGHT * ch->sustain_level) >> 3); } ch-> left_vol_level = (ch->envx * ch->volume_left) / 128; ch->right_vol_level = (ch->envx * ch->volume_right) / 128; } else { ch->state = SOUND_ATTACK; ch->envx = 0; ch->left_vol_level = 0; ch->right_vol_level = 0; S9xSetEnvRate (ch, ch->attack_rate, 1, MAX_ENVELOPE_HEIGHT); } ch->envxx = ch->envx << ENVX_SHIFT; break; case MODE_GAIN: ch->state = SOUND_GAIN; break; case MODE_INCREASE_LINEAR: ch->state = SOUND_INCREASE_LINEAR; break; case MODE_INCREASE_BENT_LINE: ch->state = SOUND_INCREASE_BENT_LINE; break; case MODE_DECREASE_LINEAR: ch->state = SOUND_DECREASE_LINEAR; break; case MODE_DECREASE_EXPONENTIAL: ch->state = SOUND_DECREASE_EXPONENTIAL; break; default: break; } S9xFixEnvelope (channel, APU.DSP [APU_GAIN + (channel << 4)], APU.DSP [APU_ADSR1 + (channel << 4)], APU.DSP [APU_ADSR2 + (channel << 4)]);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -