Permalink
Browse files

audio: more sophisticated audio slowing

  • Loading branch information...
fzurita committed Feb 21, 2016
1 parent 0127dc3 commit 9b59149d634dde21cf4fbd7c27f2d055cff8fce5
Showing with 76 additions and 72 deletions.
  1. +76 −72 jni/mupen64plus-audio-sles/main.c
@@ -31,6 +31,7 @@
#include <string.h>
#include <pthread.h>
#include <errno.h>
+#include <math.h>
#ifdef USE_SRC
#include <samplerate.h>
@@ -851,11 +852,17 @@ EXPORT void CALL AiLenChanged(void)
thread_queue_add(&audioConsumerQueue, theQueueData, 0);
}
+double TimeDiff(struct timespec* currTime, struct timespec* prevTime)
+{
+ return ((double)currTime->tv_sec+((double)currTime->tv_nsec)/1e9) -
+ ((double)prevTime->tv_sec+((double)prevTime->tv_nsec)/1e9);
+}
+
void* audioConsumer(void* param)
{
int prevQueueSize = thread_queue_length(&audioConsumerQueue);
int currQueueSize = prevQueueSize;
- int maxQueueSize = 3;
+ int maxQueueSize = 7;
static const int fullSpeed = 100;
//Game is being sped up, speed up audio
@@ -867,116 +874,113 @@ void* audioConsumer(void* param)
//Sound queue ran dry, device is running slow
int ranDry = 0;
- const int ranDryTakeAction = 20;
//adjustment used when a device running too slow
int slowAdjustment = 0;
-
- //how quickly sound speed is adjusted to match a device
- const int adjustmentPeriod = 10;
- int currentPeriod = 0;
+ int currAdjustment = 0;
+ const int maxSlowAdjustment = 2;
+ queueData* currQueueData = NULL;
+ queueData* prevQueueData = NULL;
+ struct timespec currTime;
+ struct timespec prevTime;
while(!shutdown)
{
struct timespec waitTime;
waitTime.tv_sec = 1;
waitTime.tv_nsec = 0;
- if(thread_queue_length(&audioConsumerQueue) == 0)
- {
- ++ranDry;
- }
- else
- {
- ranDry = 0;
- }
+ prevTime = currTime;
+ int queueLength = thread_queue_length(&audioConsumerQueue);
+ ranDry = queueLength == 0;// && lock.value >= (lock.limit-1);
+ clock_gettime(CLOCK_REALTIME, &currTime);
struct threadmsg msg;
int result = thread_queue_get(&audioConsumerQueue, &waitTime, &msg);
if( result != ETIMEDOUT )
{
- queueData* theQueueData = msg.data;
+ prevQueueData = currQueueData;
+ currQueueData = msg.data;
- currQueueSize = thread_queue_length(&audioConsumerQueue);
-
- //If we want to make the game run slower for us
- if(matchGameToAudio)
+ if(prevQueueData)
{
- //Game is running too fast, slow it down a little
- if(currQueueSize > maxQueueSize)
+ currQueueSize = thread_queue_length(&audioConsumerQueue);
+
+ //If we want to make the game run slower for us
+ if(matchGameToAudio)
{
- currentPeriod++;
+ //Game is running too fast, slow it down a little
+ if(currQueueSize > maxQueueSize && slowAdjustment == 0)
+ {
+ ++matchGameToAudioOffset;
+ desiredGameSpeed = fullSpeed - matchGameToAudioOffset;
+ CoreDoCommand(M64CMD_CORE_STATE_SET, M64CORE_SPEED_FACTOR, &desiredGameSpeed);
+ }
+ // Oh no! game is going too slow now, speed it up
+ else if(ranDry && matchGameToAudioOffset > 0)
+ {
+ --matchGameToAudioOffset;
+ desiredGameSpeed = fullSpeed - matchGameToAudioOffset;
+ CoreDoCommand(M64CMD_CORE_STATE_SET, M64CORE_SPEED_FACTOR, &desiredGameSpeed);
+ }
+ //Device can't keep up with the game, slow audio down
+ else if(ranDry)
+ {
+ double prevQueueLengthSec = prevQueueData->lenght/4.0/GameFreq;
+ double timeDiff = TimeDiff(&currTime, &prevTime);
- //Don't adjust it too quickly, it sounds bad
- if(currentPeriod >= adjustmentPeriod)
+ currAdjustment = timeDiff/prevQueueLengthSec*100 - 100;
+ }
+ else
{
- //Try making the audio go faster first before slowing the game down
- if(slowAdjustment > 0)
+ currAdjustment = 0;
+ }
+
+ if(currAdjustment >= 0 && currAdjustment < 100)
+ {
+ if(abs(currAdjustment - slowAdjustment) < maxSlowAdjustment)
{
- slowAdjustment--;
+ slowAdjustment = currAdjustment;
+ }
+ else if(currAdjustment < slowAdjustment)
+ {
+ slowAdjustment -= maxSlowAdjustment;
}
- //Audio can't go any faster, start slowing the game
else
{
- ++matchGameToAudioOffset;
- desiredGameSpeed = fullSpeed - matchGameToAudioOffset;
- CoreDoCommand(M64CMD_CORE_STATE_SET, M64CORE_SPEED_FACTOR, &desiredGameSpeed);
+ slowAdjustment += maxSlowAdjustment;
}
-
- currentPeriod = 0;
}
+
+ processAudio(prevQueueData->data, prevQueueData->lenght, fullSpeed - slowAdjustment);
}
- // Oh no! game is going too slow now, speed it up
- else if(ranDry > ranDryTakeAction && matchGameToAudioOffset > 0)
- {
- ranDry = 0;
- --matchGameToAudioOffset;
- desiredGameSpeed = fullSpeed - matchGameToAudioOffset;
- CoreDoCommand(M64CMD_CORE_STATE_SET, M64CORE_SPEED_FACTOR, &desiredGameSpeed);
- }
- //Device can't keep up with the game, slow audio down
- else if(ranDry > ranDryTakeAction)
+ //If we are trying to make audio catch up with video
+ else
{
- ranDry = 0;
- currentPeriod++;
-
- //Don't adjust it too quickly, it sounds bad
- if(currentPeriod >= adjustmentPeriod)
+ if(currQueueSize > maxQueueSize)
{
- slowAdjustment++;
- currentPeriod = 0;
+ int difference = currQueueSize - prevQueueSize;
+ if(difference >= 0)
+ {
+ currentSpeedFactorAdjustment += 1;
+ }
}
- }
-
- processAudio(theQueueData->data, theQueueData->lenght, fullSpeed - slowAdjustment);
- }
- //If we are trying to make audio catch up with video
- else
- {
- if(currQueueSize > maxQueueSize)
- {
- int difference = currQueueSize - prevQueueSize;
- if(difference >= 0)
+ else
{
- currentSpeedFactorAdjustment += 1;
+ currentSpeedFactorAdjustment = 0;
}
- }
- else
- {
- currentSpeedFactorAdjustment = 0;
+
+ processAudio(prevQueueData->data, prevQueueData->lenght, prevQueueData->speedFactor + currentSpeedFactorAdjustment);
}
- processAudio(theQueueData->data, theQueueData->lenght, theQueueData->speedFactor + currentSpeedFactorAdjustment);
+ free(prevQueueData->data);
+ free(prevQueueData);
}
- free(theQueueData->data);
- free(msg.data);
-
//Useful logging
//DebugMessage(M64MSG_ERROR, "audio adj = %d, length = %d, speed = %d, dry=%d, slow=%d",
- // currentSpeedFactorAdjustment, thread_queue_length(&audioConsumerQueue),
- // desiredGameSpeed, ranDry, slowAdjustment);
+ // currentSpeedFactorAdjustment, queueLength, desiredGameSpeed, ranDry, slowAdjustment);
}
}

0 comments on commit 9b59149

Please sign in to comment.