- Clamp requested pitch values to 0x3fff. Fixes games that set a too big pitch, run that voice and expect it to hit an IRQA (Romancing Saga).
- Gigaherz and Pseudonym worked out better modulation support. Should make some sounds better (FFX battle sound, etc).

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@3242 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
ramapcsx2 2010-06-19 14:52:37 +00:00
parent 22fb5d05dc
commit c996934a1e
3 changed files with 26 additions and 12 deletions

View File

@ -331,7 +331,7 @@ static void __forceinline UpdatePitch( uint coreidx, uint voiceidx )
if( (vc.Modulated==0) || (voiceidx==0) )
pitch = vc.Pitch;
else
pitch = (vc.Pitch*(32768 + abs(Cores[coreidx].Voices[voiceidx-1].OutX)))>>15;
pitch = (vc.Pitch*(32768 + Cores[coreidx].Voices[voiceidx-1].OutX))>>15;
vc.SP+=pitch;
}
@ -573,18 +573,28 @@ static __forceinline StereoOut32 MixVoice( uint coreidx, uint voiceidx )
CalculateADSR( thiscore, voiceidx );
Value = MulShr32( Value, vc.ADSR.Value );
vc.OutX = Value; // Note: All values recorded into OutX (may be used for modulation later)
if(voiceidx<23 && Cores[coreidx].Voices[voiceidx+1].Modulated)
Value=0;
// Store Value for eventual modulation later
// Pseudonym's Crest calculation idea. Actually calculates a crest, unlike the old code which was just peak.
u32 Amplitude = std::abs(Value);
if(Amplitude < vc.NextCrest)
{
vc.OutX = vc.NextCrest;
vc.NextCrest = 0;
}
if(Amplitude > vc.PrevAmp)
{
vc.NextCrest = Amplitude;
}
vc.PrevAmp = Amplitude;
if( IsDevBuild )
DebugCores[coreidx].Voices[voiceidx].displayPeak = std::max(DebugCores[coreidx].Voices[voiceidx].displayPeak,abs(vc.OutX));
DebugCores[coreidx].Voices[voiceidx].displayPeak = std::max(DebugCores[coreidx].Voices[voiceidx].displayPeak,(s32)vc.OutX);
// Write-back of raw voice data (post ADSR applied)
if (voiceidx==1) spu2M_WriteFast( ( (0==coreidx) ? 0x400 : 0xc00 ) + OutPos, Value );
else if (voiceidx==3) spu2M_WriteFast( ( (0==coreidx) ? 0x600 : 0xe00 ) + OutPos, Value );
if (voiceidx==1) spu2M_WriteFast( ( (0==coreidx) ? 0x400 : 0xc00 ) + OutPos, vc.OutX );
else if (voiceidx==3) spu2M_WriteFast( ( (0==coreidx) ? 0x600 : 0xe00 ) + OutPos, vc.OutX );
return ApplyVolume( StereoOut32( Value, Value ), vc.Volume );
}

View File

@ -143,7 +143,7 @@ struct V_Voice
// Envelope
V_ADSR ADSR;
// Pitch (also Reg_PITCH)
s16 Pitch;
u16 Pitch;
// Loop Start address (also Reg_LSAH/L)
u32 LoopStartA;
// Sound Start address (also Reg_SSAH/L)
@ -180,7 +180,9 @@ struct V_Voice
s32 PV1;
// Last outputted audio value, used for voice modulation.
s32 OutX;
u32 OutX;
u32 NextCrest; // temp value for Crest calculation
u32 PrevAmp; // temp value for Crest calculation (abs of last value)
// SBuffer now points directly to an ADPCM cache entry.
s16 *SBuffer;

View File

@ -144,7 +144,7 @@ void V_Core::Reset( int index )
VoiceGates[v].WetL = -1;
VoiceGates[v].WetR = -1;
Voices[v].Volume = V_VolumeSlideLR::Max;
Voices[v].Volume = V_VolumeSlideLR(0,0); // V_VolumeSlideLR::Max;
Voices[v].SCurrent = 28;
Voices[v].ADSR.Value = 0;
@ -263,6 +263,8 @@ void V_Voice::Start()
PV1 = PV2 = 0;
PV3 = PV4 = 0;
PrevAmp = 0;
NextCrest = 0;
}
else
{
@ -754,7 +756,7 @@ static void __fastcall RegWrite_VoiceParams( u16 value )
break;
case 2:
thisvoice.Pitch = value;
thisvoice.Pitch = value & 0x3fff;
break;
case 3: // ADSR1 (Envelope)