Permalink
Browse files

audio: algorithm tweaks

  • Loading branch information...
fzurita committed Mar 5, 2016
1 parent 2022a0a commit 18ea68a88948b0e241d51a51387d6d1cd313b159
Showing with 46 additions and 42 deletions.
  1. +44 −40 jni/mupen64plus-audio-sles/main.cpp
  2. +2 −2 jni/mupen64plus-core/src/main/main.c
@@ -676,8 +676,8 @@ bool isSpeedLimiterEnabled(void)
EXPORT void CALL AiLenChanged(void)
{
static const bool sleepPerfFixEnabled = false;
static const double minSleepNeeded = -0.1;
static const double maxSleepNeeded = 0.1;
static const double minSleepNeeded = -0.05;
static const double maxSleepNeeded = 0.05;
static bool resetOnce = false;
static unsigned long totalElapsedSamples = 0;
static double gameStartTime = 0;
@@ -803,24 +803,24 @@ void* audioConsumer(void* param)
int prevQueueSize = thread_queue_length(&audioConsumerQueue);
int currQueueSize = prevQueueSize;
int maxQueueSize = TargetSecondaryBuffers + 10;
int maxQueueSize = TargetSecondaryBuffers + 20;
int minQueueSize = TargetSecondaryBuffers;
int desiredGameSpeed = 100;
static const int fullSpeed = 100;
bool drainQueue = false;
//Sound queue ran dry, device is running slow
int ranDry = 0;
//adjustment used when a device running too slow
double slowAdjustment = 0;
double currAdjustment = 0;
double slowAdjustment = 1.0;
double currAdjustment = 1.0;
//how quickly to return to original speed
const double returnSpeed = 0.10;
const double minSlowValue = 0.2;
const double maxSlowValue = 3.0;
const double catchUpOffset = 0.05;
//Adjust tempo in x% increments so it's more steady
int increments = 4;
const double catchUpOffset = increments*2/100.0;
queueData* currQueueData = NULL;
struct timespec currTime;
struct timespec prevTime;
@@ -838,8 +838,8 @@ void* audioConsumer(void* param)
float timePerBuffer = 1.0*SecondaryBufferSize/GameFreq;
float feedTimes[feedTimeWindowSize];
float gameTimes[feedTimeWindowSize];
float averageGameTime = 0.0;
float averageFeedTime = 0.0;
float averageGameTime = 0.01666;
float averageFeedTime = 0.01666;
while(!shutdown)
{
@@ -851,50 +851,31 @@ void* audioConsumer(void* param)
clock_gettime(CLOCK_REALTIME, &prevTime);
int result = thread_queue_get(&audioConsumerQueue, &waitTime, &msg);
clock_gettime(CLOCK_REALTIME, &currTime);
if( result != ETIMEDOUT )
{
int threadQueueLength = thread_queue_length(&audioConsumerQueue);
//Figure out how much to slow down by
float timeDiff = TimeDiff(&currTime, &prevTime);
//sometimes this ends up as less than 0, not sure how
if(timeDiff > 0)
{
feedTimes[feedTimeIndex] = timeDiff;
}
averageFeedTime = GetAverageTime(feedTimes, feedTimesSet ? feedTimeWindowSize : (feedTimeIndex+1));
currQueueData = (queueData*)msg.data;
gameTimes[feedTimeIndex] = (float)currQueueData->lenght/(float)N64_SAMPLE_BYTES/(float)GameFreq;
averageGameTime = GetAverageTime(gameTimes, feedTimesSet ? feedTimeWindowSize : (feedTimeIndex+1));
++feedTimeIndex;
if(feedTimeIndex == feedTimeWindowSize)
{
feedTimeIndex = 0;
feedTimesSet = true;
}
int dataLength = currQueueData->lenght;
float temp = averageGameTime/averageFeedTime;
//Game is running too fast speed up audio
if(slesQueueLength > maxQueueSize)
if((slesQueueLength > maxQueueSize || drainQueue) && !ranDry)
{
drainQueue = true;
currAdjustment = temp + catchUpOffset;
}
//Device can't keep up with the game or we have too much in the queue after slowing it down
else if(ranDry)
{
drainQueue = false;
currAdjustment = temp - catchUpOffset/2.0;
}
else if(!ranDry && slesQueueLength < maxQueueSize)
{
currAdjustment = temp;
currAdjustment = (double)speed_factor/100.0;;
}
//Allow the tempo to slow quickly with no minimum value change, but restore original tempo more slowly.
@@ -916,26 +897,49 @@ void* audioConsumer(void* param)
slowAdjustment = currAdjustment;
}
//Adjyst tempo in x% increments so it's more steady
int increments = 4;
//Adjust tempo in x% increments so it's more steady
int temp2 = ((int)(slowAdjustment*100))/increments;
temp2 *= increments;
slowAdjustment = ((double)temp2)/100;
soundTouch.setTempo(slowAdjustment);
}
processAudio(currQueueData->data, currQueueData->lenght);
processAudio(currQueueData->data, dataLength);
free(currQueueData->data);
free(currQueueData);
//Useful logging
//if(slesQueueLength == 0)
//{
// DebugMessage(M64MSG_ERROR, "sles_length=%d, thread_length=%d speed=%d, dry=%d, slow_adj=%f, curr_adj=%f, temp=%f, feed_time=%f, game_time=%f",
// slesQueueLength, threadQueueLength, desiredGameSpeed, ranDry, slowAdjustment, currAdjustment, temp, averageFeedTime, averageGameTime);
// DebugMessage(M64MSG_ERROR, "sles_length=%d, thread_length=%d, dry=%d, slow_adj=%f, curr_adj=%f, temp=%f, feed_time=%f, game_time=%f",
// slesQueueLength, threadQueueLength, ranDry, slowAdjustment, currAdjustment, temp, averageFeedTime, averageGameTime);
//}
//Calculate rates
clock_gettime(CLOCK_REALTIME, &currTime);
//Figure out how much to slow down by
float timeDiff = TimeDiff(&currTime, &prevTime);
//sometimes this ends up as less than 0, not sure how
if(timeDiff > 0)
{
feedTimes[feedTimeIndex] = timeDiff;
}
averageFeedTime = GetAverageTime(feedTimes, feedTimesSet ? feedTimeWindowSize : (feedTimeIndex+1));
gameTimes[feedTimeIndex] = (float)dataLength/(float)N64_SAMPLE_BYTES/(float)GameFreq;
averageGameTime = GetAverageTime(gameTimes, feedTimesSet ? feedTimeWindowSize : (feedTimeIndex+1));
++feedTimeIndex;
if(feedTimeIndex == feedTimeWindowSize)
{
feedTimeIndex = 0;
feedTimesSet = true;
}
}
}
@@ -742,8 +742,8 @@ static void apply_speed_limiter(void)
static unsigned int VIDeltasIndex;
//Reset if the sleep needed is an unreasonable value
static const double minSleepNeeded = -100;
static const double maxSleepNeeded = 100;
static const double minSleepNeeded = -50;
static const double maxSleepNeeded = 50;
static unsigned long totalVIs = 0;
static int resetOnce = 0;
static int lastSpeedFactor = 100;

0 comments on commit 18ea68a

Please sign in to comment.