SPU2X: New time stretcher: Improved behavior on extremes.

1. Much better behavior at extreme low/high FPS (less skips/lower latency).
2. As a result, I was able to reduce internal latency by 50% (50ms config now equals 100ms before).

Recommended latency config for stretcher: 100ms.
For rhythm games, if your FPS is very stable, I recommend 50ms.

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@4834 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
avihal@gmail.com 2011-07-31 11:27:50 +00:00
parent 52a0eb047d
commit 92e67c218a
1 changed files with 13 additions and 6 deletions

View File

@ -111,7 +111,7 @@ T clamp(T val, T min, T max){
void SndBuffer::UpdateTempoChangeSoundTouch2() void SndBuffer::UpdateTempoChangeSoundTouch2()
{ {
//base aim at buffer filled % //base aim at buffer filled %
float targetFullness=0.1; float baseTargetFullness=0.05;
//threshold params (hysteresis) //threshold params (hysteresis)
static const float hys_ok_factor=1.03; static const float hys_ok_factor=1.03;
@ -121,6 +121,7 @@ void SndBuffer::UpdateTempoChangeSoundTouch2()
//state vars //state vars
static bool inside_hysteresis=false; static bool inside_hysteresis=false;
static int hys_ok_count=0; static int hys_ok_count=0;
static float dynamicTargetFullness=baseTargetFullness;
//some precalculated values //some precalculated values
static const float hys_ok_min=1.0/hys_ok_factor; static const float hys_ok_min=1.0/hys_ok_factor;
@ -132,12 +133,17 @@ void SndBuffer::UpdateTempoChangeSoundTouch2()
static float last_bufferFullness=0; static float last_bufferFullness=0;
if(last_bufferFullness != bufferFullness){// only recalculate if buffer changes if(last_bufferFullness != bufferFullness){// only recalculate if buffer changes
last_bufferFullness = bufferFullness; last_bufferFullness = bufferFullness;
float tempoAdjust=bufferFullness/targetFullness; float tempoAdjust=bufferFullness/dynamicTargetFullness;
float avgerage = addToAvg(tempoAdjust); float avgerage = addToAvg(tempoAdjust);
tempoAdjust = avgerage; tempoAdjust = avgerage;
if( tempoAdjust>1.2 ) tempoAdjust=0.2+pow(tempoAdjust-0.2f, 3);//reduce latency for faster speeds only tempoAdjust = clamp( tempoAdjust, 0.05f, 10.0f);
tempoAdjust = clamp( tempoAdjust, 0.1f, 10.0f); dynamicTargetFullness += (baseTargetFullness/tempoAdjust - dynamicTargetFullness)/50.0;
if(
tempoAdjust == clamp(tempoAdjust, 0.9f, 1.1f)
&& dynamicTargetFullness == clamp( dynamicTargetFullness, baseTargetFullness*0.9f, baseTargetFullness*1.1f)
)
dynamicTargetFullness=baseTargetFullness;
if( !inside_hysteresis ) if( !inside_hysteresis )
{ {
@ -168,7 +174,8 @@ void SndBuffer::UpdateTempoChangeSoundTouch2()
wxTimeSpan delta = unow.Subtract(last); wxTimeSpan delta = unow.Subtract(last);
if(delta.GetMilliseconds()>1000){//report buffers state and tempo adjust every second if(delta.GetMilliseconds()>1000){//report buffers state and tempo adjust every second
printf("buffers: %f, actual adjust: %f, iterations: %d\n", bufferFullness, tempoAdjust, iters); printf("buffers[->%.2f]: %.3f (%3.0f%%), tempo adjust: %f, compensated target: %.3f, iterations: %d\n",
(double)baseTargetFullness, (double)bufferFullness, (double)(100.0*bufferFullness/baseTargetFullness), (double)tempoAdjust, (double)dynamicTargetFullness, iters);
last=unow; last=unow;
iters=0; iters=0;
} }