Permalink
Browse files

Sas: Correct delay in playing samples.

We still need to walk during the delay to "use it up."  Need to test more
to see if we can just walk once directly into ATTACK - might depend on
pitch.

This also makes the first play ignore the resampleHist, which matches
samples to tests properly, and ignores linear interp for exact pitch.

These changes fix all the sascore tests that used to work.
  • Loading branch information...
unknownbrackets committed May 29, 2018
1 parent 07e178a commit b56e3e8e9429682944fd8e6316f4a849f5772111
Showing with 20 additions and 5 deletions.
  1. +20 −5 Core/HW/SasAudio.cpp
View
@@ -508,15 +508,30 @@ void SasInstance::MixVoice(SasVoice &voice) {
ERROR_LOG(SCESAS, "Too many samples to read (%d)! This shouldn't happen.", samplesToRead);
samplesToRead = ARRAY_SIZE(mixTemp_) - 2;
}
voice.ReadSamples(&mixTemp_[2], samplesToRead);
int tempPos = 2 + samplesToRead;
int readPos = 2;
if (voice.envelope.NeedsKeyOn()) {
readPos = 0;
samplesToRead += 2;
}
voice.ReadSamples(&mixTemp_[readPos], samplesToRead);
int tempPos = readPos + samplesToRead;
for (int i = 0; i < delay; ++i) {
// Walk the curve. This means we'll reach ATTACK already, likely.
// This matches the results of tests (but maybe we can just remove the STATE_KEYON_STEP hack.)
voice.envelope.Step();
}
const bool needsInterp = voicePitch != PSP_SAS_PITCH_BASE || (sampleFrac & PSP_SAS_PITCH_MASK) != 0;
for (int i = delay; i < grainSize; i++) {
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;
int sample = s[0];
if (needsInterp) {
int f = sampleFrac & PSP_SAS_PITCH_MASK;
sample = (s[0] * (PSP_SAS_PITCH_MASK - f) + s[1] * f) >> PSP_SAS_PITCH_BASE_SHIFT;
}
sampleFrac += voicePitch;
// The maximum envelope height (PSP_SAS_ENVELOPE_HEIGHT_MAX) is (1 << 30) - 1.
@@ -541,7 +556,7 @@ void SasInstance::MixVoice(SasVoice &voice) {
voice.resampleHist[0] = mixTemp_[tempPos - 2];
voice.resampleHist[1] = mixTemp_[tempPos - 1];
voice.sampleFrac = sampleFrac - (tempPos - 2) * PSP_SAS_PITCH_BASE;;
voice.sampleFrac = sampleFrac - (tempPos - 2) * PSP_SAS_PITCH_BASE;
if (voice.HaveSamplesEnded())
voice.envelope.End();

0 comments on commit b56e3e8

Please sign in to comment.