diff --git a/Core/HLE/sceSas.cpp b/Core/HLE/sceSas.cpp index a0450efa5a..c7dc08805e 100644 --- a/Core/HLE/sceSas.cpp +++ b/Core/HLE/sceSas.cpp @@ -536,7 +536,7 @@ static u32 sceSasSetSL(u32 core, int voiceNum, int level) { DEBUG_LOG(SCESAS, "sceSasSetSL(%08x, %i, %08x)", core, voiceNum, level); __SasDrain(); SasVoice &v = sas->voices[voiceNum]; - v.envelope.sustainLevel = level; + v.envelope.SetSustainLevel(level); return 0; } @@ -556,10 +556,7 @@ static u32 sceSasSetADSR(u32 core, int voiceNum, int flag, int a, int d, int s, __SasDrain(); SasVoice &v = sas->voices[voiceNum]; - if ((flag & 0x1) != 0) v.envelope.attackRate = a; - if ((flag & 0x2) != 0) v.envelope.decayRate = d; - if ((flag & 0x4) != 0) v.envelope.sustainRate = s; - if ((flag & 0x8) != 0) v.envelope.releaseRate = r; + v.envelope.SetRate(flag, a, d, s, r); return 0; } @@ -602,10 +599,7 @@ static u32 sceSasSetADSRMode(u32 core, int voiceNum, int flag, int a, int d, int DEBUG_LOG(SCESAS, "sceSasSetADSRMode(%08x, %i, %i, %08x, %08x, %08x, %08x)", core, voiceNum, flag, a, d, s, r); __SasDrain(); SasVoice &v = sas->voices[voiceNum]; - if ((flag & 0x1) != 0) v.envelope.attackType = a; - if ((flag & 0x2) != 0) v.envelope.decayType = d; - if ((flag & 0x4) != 0) v.envelope.sustainType = s; - if ((flag & 0x8) != 0) v.envelope.releaseType = r; + v.envelope.SetEnvelope(flag, a, d, s, r); return 0; } diff --git a/Core/HW/SasAudio.cpp b/Core/HW/SasAudio.cpp index 08393bf485..a8a2f6d56d 100644 --- a/Core/HW/SasAudio.cpp +++ b/Core/HW/SasAudio.cpp @@ -318,6 +318,32 @@ static int getSustainLevel(int bitfield1) { return ((bitfield1 & 0x000F) + 1) << 26; } +void ADSREnvelope::SetEnvelope(int flag, int a, int d, int s, int r) { + if ((flag & 0x1) != 0) + attackType = a; + if ((flag & 0x2) != 0) + decayType = d; + if ((flag & 0x4) != 0) + sustainType = s; + if ((flag & 0x8) != 0) + releaseType = r; + + if (PSP_CoreParameter().compat.flags().RockmanDash2SoundFix && sustainType == PSP_SAS_ADSR_CURVE_MODE_LINEAR_INCREASE) { + sustainType = PSP_SAS_ADSR_CURVE_MODE_LINEAR_DECREASE; + } +} + +void ADSREnvelope::SetRate(int flag, int a, int d, int s, int r) { + if ((flag & 0x1) != 0) + attackRate = a; + if ((flag & 0x2) != 0) + decayRate = d; + if ((flag & 0x4) != 0) + sustainRate = s; + if ((flag & 0x8) != 0) + releaseRate = r; +} + void ADSREnvelope::SetSimpleEnvelope(u32 ADSREnv1, u32 ADSREnv2) { attackRate = getAttackRate(ADSREnv1); attackType = getAttackType(ADSREnv1); @@ -329,6 +355,10 @@ void ADSREnvelope::SetSimpleEnvelope(u32 ADSREnv1, u32 ADSREnv2) { releaseType = getReleaseType(ADSREnv2); sustainLevel = getSustainLevel(ADSREnv1); + if (PSP_CoreParameter().compat.flags().RockmanDash2SoundFix && sustainType == PSP_SAS_ADSR_CURVE_MODE_LINEAR_INCREASE) { + sustainType = PSP_SAS_ADSR_CURVE_MODE_LINEAR_DECREASE; + } + if (attackRate < 0 || decayRate < 0 || sustainRate < 0 || releaseRate < 0) { ERROR_LOG_REPORT(SASMIX, "Simple ADSR resulted in invalid rates: %04x, %04x", ADSREnv1, ADSREnv2); } @@ -895,11 +925,7 @@ inline void ADSREnvelope::Step() { SetState(STATE_SUSTAIN); break; case STATE_SUSTAIN: - if (PSP_CoreParameter().compat.flags().RockmanDash2SoundFix && sustainType == PSP_SAS_ADSR_CURVE_MODE_LINEAR_INCREASE) { - WalkCurve(PSP_SAS_ADSR_CURVE_MODE_LINEAR_DECREASE, sustainRate); - } else { - WalkCurve(sustainType, sustainRate); - } + WalkCurve(sustainType, sustainRate); if (height_ <= 0) { height_ = 0; SetState(STATE_RELEASE); diff --git a/Core/HW/SasAudio.h b/Core/HW/SasAudio.h index 4e9670c136..bae8b738d9 100644 --- a/Core/HW/SasAudio.h +++ b/Core/HW/SasAudio.h @@ -151,6 +151,11 @@ class ADSREnvelope { public: ADSREnvelope(); void SetSimpleEnvelope(u32 ADSREnv1, u32 ADSREnv2); + void SetEnvelope(int flag, int a, int d, int s, int r); + void SetRate(int flag, int a, int d, int s, int r); + void SetSustainLevel(int sl) { + sustainLevel = sl; + } void WalkCurve(int type, int rate); @@ -170,16 +175,6 @@ public: return state_ == STATE_OFF; } - int attackRate; - int decayRate; - int sustainRate; - int releaseRate; - int attackType; - int decayType; - int sustainType; - int sustainLevel; - int releaseType; - void DoState(PointerWrap &p); private: @@ -197,6 +192,16 @@ private: }; void SetState(ADSRState state); + int attackRate; + int decayRate; + int sustainRate; + int releaseRate; + int attackType; + int decayType; + int sustainType; + int sustainLevel; + int releaseType; + ADSRState state_; s64 height_; // s64 to avoid having to care about overflow when calculating. TODO: this should be fine as s32 };