Permalink
Browse files

audio: Audio now stays in sync with video without pitch adjustment

  • Loading branch information...
fzurita committed Feb 21, 2016
1 parent f2d90cf commit e09802d20dd11a7b1445d54fee01c967336187e1
Showing with 57 additions and 11 deletions.
  1. +57 −11 jni/mupen64plus-audio-sles/main.c
@@ -44,6 +44,7 @@
#include "m64p_config.h"
#include "m64p_plugin.h"
#include "m64p_types.h"
#include "m64p_frontend.h"
#include "main.h"
#include "osal_dynamiclib.h"
#include "threadqueue.h"
@@ -141,6 +142,7 @@ static pthread_t audioConsumerThread;
static struct threadqueue audioConsumerQueue;
static volatile int shutdown = 1;
static volatile int matchGameToAudio = 1;
/* Samplerate*/
#ifdef USE_SRC
@@ -189,6 +191,7 @@ ptr_ConfigGetParamInt ConfigGetParamInt = NULL;
ptr_ConfigGetParamFloat ConfigGetParamFloat = NULL;
ptr_ConfigGetParamBool ConfigGetParamBool = NULL;
ptr_ConfigGetParamString ConfigGetParamString = NULL;
ptr_CoreDoCommand CoreDoCommand = NULL;
/* Global functions */
static void DebugMessage(int level, const char *message, ...)
@@ -704,10 +707,12 @@ EXPORT m64p_error CALL PluginStartup(m64p_dynlib_handle CoreLibHandle, void *Con
ConfigGetParamFloat = (ptr_ConfigGetParamFloat) osal_dynlib_getproc(CoreLibHandle, "ConfigGetParamFloat");
ConfigGetParamBool = (ptr_ConfigGetParamBool) osal_dynlib_getproc(CoreLibHandle, "ConfigGetParamBool");
ConfigGetParamString = (ptr_ConfigGetParamString) osal_dynlib_getproc(CoreLibHandle, "ConfigGetParamString");
CoreDoCommand = (ptr_CoreDoCommand) osal_dynlib_getproc(CoreLibHandle, "CoreDoCommand");
if (!ConfigOpenSection || !ConfigDeleteSection || !ConfigSetParameter || !ConfigGetParameter ||
!ConfigSetDefaultInt || !ConfigSetDefaultFloat || !ConfigSetDefaultBool || !ConfigSetDefaultString ||
!ConfigGetParamInt || !ConfigGetParamFloat || !ConfigGetParamBool || !ConfigGetParamString)
!ConfigGetParamInt || !ConfigGetParamFloat || !ConfigGetParamBool || !ConfigGetParamString ||
!CoreDoCommand)
return M64ERR_INCOMPATIBLE;
/* ConfigSaveSection was added in Config API v2.1.0 */
@@ -852,13 +857,19 @@ void* audioConsumer(void* param)
int currQueueSize = prevQueueSize;
int maxQueueSize = 3;
int currentSpeedFactorAdjustment = 0;
static const int fullSpeed = 100;
int matchGameToAudioOffset = 0;
int desiredGameSpeed = 100;
int ranDry = 0;
while(!shutdown)
{
struct timespec waitTime;
waitTime.tv_sec = 1;
waitTime.tv_nsec = 0;
ranDry = thread_queue_length(&audioConsumerQueue) == 0;
struct threadmsg msg;
int result = thread_queue_get(&audioConsumerQueue, &waitTime, &msg);
@@ -868,24 +879,49 @@ void* audioConsumer(void* param)
currQueueSize = thread_queue_length(&audioConsumerQueue);
if(currQueueSize > maxQueueSize)
//If we are trying to make audio catch up with video
if(matchGameToAudio)
{
int difference = currQueueSize - prevQueueSize;
if(difference >= 0)
//Game is running too fast, slow it down a little
if(currQueueSize > maxQueueSize)
{
++matchGameToAudioOffset;
desiredGameSpeed = fullSpeed - matchGameToAudioOffset;
CoreDoCommand(M64CMD_CORE_STATE_SET, M64CORE_SPEED_FACTOR, &desiredGameSpeed);
}
// Oh no!, game is going to slow now, speed it up
else if(ranDry && matchGameToAudioOffset > 0)
{
--matchGameToAudioOffset;
}
else
{
currentSpeedFactorAdjustment += 1;
matchGameToAudioOffset = 0;
}
processAudio(theQueueData->data, theQueueData->lenght, fullSpeed);
}
//If we want to make the game run slower for us
else
{
currentSpeedFactorAdjustment = 0;
if(currQueueSize > maxQueueSize)
{
int difference = currQueueSize - prevQueueSize;
if(difference >= 0)
{
currentSpeedFactorAdjustment += 1;
}
}
else
{
currentSpeedFactorAdjustment = 0;
}
processAudio(theQueueData->data, theQueueData->lenght, theQueueData->speedFactor + currentSpeedFactorAdjustment);
}
processAudio(theQueueData->data, theQueueData->lenght, theQueueData->speedFactor + currentSpeedFactorAdjustment);
free(theQueueData->data);
free(msg.data);
//DebugMessage(M64MSG_ERROR, "Current adjustment = %d, Queue length = %d", currentSpeedFactorAdjustment, thread_queue_length(&audioConsumerQueue));
}
}
@@ -930,8 +966,6 @@ void processAudio(const unsigned char* buffer, unsigned int length, unsigned int
int newsamplerate = OutputFreq * 100 / speedFactor;
int oldsamplerate = GameFreq;
//DebugMessage(M64MSG_ERROR, "sample rate = %d", newsamplerate);
while (primaryBufferPos >= ((secondaryBufferBytes * oldsamplerate) / newsamplerate))
{
pthread_mutex_lock(&(lock.mutex));
@@ -1012,6 +1046,18 @@ EXPORT void CALL SetSpeedFactor(int percentage)
return;
if (percentage >= 10 && percentage <= 300)
speed_factor = percentage;
if(percentage == 100)
{
matchGameToAudio = 1;
}
//We don't want to snap ourselves out of this mode
if(matchGameToAudio && (percentage > 115 || percentage < 85))
{
matchGameToAudio = 0;
}
}
EXPORT void CALL VolumeMute(void)

0 comments on commit e09802d

Please sign in to comment.