mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-02-25 08:33:27 +00:00
Fix bug causing stack overflow in SasAudio, #9190. Move the mixbuffer off the stack for easier-to-diagnose error (this trashed the info I needed to debug pretty badly...)
This commit is contained in:
parent
c89ad2294c
commit
ad04f97acb
@ -493,32 +493,30 @@ void SasInstance::MixVoice(SasVoice &voice) {
|
||||
++delay;
|
||||
}
|
||||
|
||||
// Resample to the correct pitch, writing exactly "grainSize" samples.
|
||||
// Resample to the correct pitch, writing exactly "grainSize" samples. We need a buffer that can
|
||||
// fit 4x that, as the max pitch is 0x4000.
|
||||
// TODO: Special case no-resample case (and 2x and 0.5x) for speed, it's not uncommon
|
||||
int16_t temp[PSP_SAS_MAX_GRAIN + 2];
|
||||
|
||||
// Sanity check sampleFrac. Should be at most 2 samples ahead, if more then something has gone wrong (pitch
|
||||
// cannot legally be more than 2x, though games might do more so we leave a margin...).
|
||||
// In the future we should figure out all these cases.
|
||||
u32 sampleFrac = voice.sampleFrac;
|
||||
if (sampleFrac > PSP_SAS_PITCH_BASE * 4)
|
||||
sampleFrac = 0;
|
||||
|
||||
// Two passes: First read, then resample.
|
||||
temp[0] = voice.resampleHist[0];
|
||||
temp[1] = voice.resampleHist[1];
|
||||
mixTemp_[0] = voice.resampleHist[0];
|
||||
mixTemp_[1] = voice.resampleHist[1];
|
||||
|
||||
int samplesToRead = (sampleFrac + voice.pitch * (grainSize - delay)) >> PSP_SAS_PITCH_BASE_SHIFT;
|
||||
voice.ReadSamples(&temp[2], samplesToRead);
|
||||
int voicePitch = voice.pitch;
|
||||
u32 sampleFrac = voice.sampleFrac;
|
||||
int samplesToRead = (sampleFrac + voicePitch * (grainSize - delay)) >> PSP_SAS_PITCH_BASE_SHIFT;
|
||||
if (samplesToRead > ARRAY_SIZE(mixTemp_) - 2) {
|
||||
PanicAlert("Too many samples to read! This shouldn't happen.");
|
||||
}
|
||||
voice.ReadSamples(&mixTemp_[2], samplesToRead);
|
||||
int tempPos = 2 + samplesToRead;
|
||||
|
||||
for (int i = delay; i < grainSize; i++) {
|
||||
const int16_t *s = temp + (sampleFrac >> PSP_SAS_PITCH_BASE_SHIFT);
|
||||
const int16_t *s = mixTemp_ + (sampleFrac >> PSP_SAS_PITCH_BASE_SHIFT);
|
||||
|
||||
// Linear interpolation. Good enough. Need to make resampleHist bigger if we want more.
|
||||
int f = sampleFrac & PSP_SAS_PITCH_MASK;
|
||||
int sample = (s[0] * (PSP_SAS_PITCH_MASK - f) + s[1] * f) >> PSP_SAS_PITCH_BASE_SHIFT;
|
||||
sampleFrac += voice.pitch;
|
||||
sampleFrac += voicePitch;
|
||||
|
||||
// The maximum envelope height (PSP_SAS_ENVELOPE_HEIGHT_MAX) is (1 << 30) - 1.
|
||||
// Reduce it to 14 bits, by shifting off 15. Round up by adding (1 << 14) first.
|
||||
@ -539,8 +537,8 @@ void SasInstance::MixVoice(SasVoice &voice) {
|
||||
sendBuffer[i * 2 + 1] += sample * voice.effectRight >> 12;
|
||||
}
|
||||
|
||||
voice.resampleHist[0] = temp[tempPos - 2];
|
||||
voice.resampleHist[1] = temp[tempPos - 1];
|
||||
voice.resampleHist[0] = mixTemp_[tempPos - 2];
|
||||
voice.resampleHist[1] = mixTemp_[tempPos - 1];
|
||||
|
||||
voice.sampleFrac = sampleFrac - (tempPos - 2) * PSP_SAS_PITCH_BASE;;
|
||||
|
||||
|
@ -311,4 +311,5 @@ public:
|
||||
private:
|
||||
SasReverb reverb_;
|
||||
int grainSize;
|
||||
int16_t mixTemp_[PSP_SAS_MAX_GRAIN * 4 + 2 + 8]; // some extra margin for very high pitches.
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user