mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
b=1012609 improve PeriodicWave phase-wrapping logic r=rillian
This approach takes advantage of the fact that periodicWaveSize is a power of 2 and uses unsigned integer modulo arithmetic to find the appropriate phase of the period. --HG-- extra : rebase_source : bb5fc413785d5f12a76cff4cbb5ba2ed5e979b41
This commit is contained in:
parent
97db07c4dd
commit
1935e660b0
@ -373,6 +373,10 @@ public:
|
||||
MOZ_ASSERT(mPeriodicWave, "No custom waveform data");
|
||||
|
||||
uint32_t periodicWaveSize = mPeriodicWave->periodicWaveSize();
|
||||
// Mask to wrap wave data indices into the range [0,periodicWaveSize).
|
||||
uint32_t indexMask = periodicWaveSize - 1;
|
||||
MOZ_ASSERT(periodicWaveSize && (periodicWaveSize & indexMask) == 0,
|
||||
"periodicWaveSize must be power of 2");
|
||||
float* higherWaveData = nullptr;
|
||||
float* lowerWaveData = nullptr;
|
||||
float tableInterpolationFactor;
|
||||
@ -387,14 +391,15 @@ public:
|
||||
lowerWaveData,
|
||||
higherWaveData,
|
||||
tableInterpolationFactor);
|
||||
mPhase = fmod(mPhase, periodicWaveSize);
|
||||
// Bilinear interpolation between adjacent samples in each table.
|
||||
uint32_t j1 = floor(mPhase);
|
||||
float floorPhase = floorf(mPhase);
|
||||
uint32_t j1 = floorPhase;
|
||||
j1 &= indexMask;
|
||||
uint32_t j2 = j1 + 1;
|
||||
if (j2 >= periodicWaveSize) {
|
||||
j2 -= periodicWaveSize;
|
||||
}
|
||||
float sampleInterpolationFactor = mPhase - j1;
|
||||
j2 &= indexMask;
|
||||
|
||||
float sampleInterpolationFactor = mPhase - floorPhase;
|
||||
|
||||
float lower = (1.0f - sampleInterpolationFactor) * lowerWaveData[j1] +
|
||||
sampleInterpolationFactor * lowerWaveData[j2];
|
||||
float higher = (1.0f - sampleInterpolationFactor) * higherWaveData[j1] +
|
||||
@ -402,7 +407,10 @@ public:
|
||||
aOutput[i] = (1.0f - tableInterpolationFactor) * lower +
|
||||
tableInterpolationFactor * higher;
|
||||
|
||||
mPhase += basePhaseIncrement * mFinalFrequency;
|
||||
// Calculate next phase position from wrapped value j1 to avoid loss of
|
||||
// precision at large values.
|
||||
mPhase =
|
||||
j1 + sampleInterpolationFactor + basePhaseIncrement * mFinalFrequency;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user