Permalink
Browse files

audio: Made audio threaded. This breaks sync game to audio

  • Loading branch information...
fzurita committed Feb 20, 2016
1 parent 99c8085 commit a6236ba2f7b6d90be3ffcd35abec02cc4df784dc
@@ -32,11 +32,12 @@ LOCAL_C_INCLUDES := \
LOCAL_SRC_FILES := \
main.c \
osal_dynamiclib_unix.c \
+ threadqueue.c \
LOCAL_CFLAGS := \
$(COMMON_CFLAGS) \
-DUSE_SRC \
-LOCAL_LDLIBS := -lOpenSLES
+LOCAL_LDLIBS := -lOpenSLES -L$(SYSROOT)/usr/lib -llog
include $(BUILD_SHARED_LIBRARY)
@@ -30,6 +30,7 @@
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
+#include <errno.h>
#ifdef USE_SRC
#include <samplerate.h>
@@ -45,6 +46,7 @@
#include "m64p_types.h"
#include "main.h"
#include "osal_dynamiclib.h"
+#include "threadqueue.h"
typedef struct threadLock_
{
@@ -126,6 +128,19 @@ static int OutputFreq;
/* Indicate that the audio plugin failed to initialize, so the emulator can keep running without sound */
static int critical_failure = 0;
+typedef struct queueData_
+{
+ unsigned char* data;
+ unsigned int lenght;
+} queueData;
+
+void processAudio(const unsigned char* buffer, int length);
+static void* audioConsumer(void*);
+static pthread_t audioConsumerThread;
+static struct threadqueue audioConsumerQueue;
+
+static volatile int shutdown = 1;
+
/* Samplerate*/
#ifdef USE_SRC
static float *_src = NULL;
@@ -208,6 +223,14 @@ void queueCallback(SLAndroidSimpleBufferQueueItf caller, void *context)
static void CloseAudio(void)
{
+ if(shutdown == 0)
+ {
+ shutdown = 1;
+ pthread_join(audioConsumerThread,NULL);
+
+ thread_queue_cleanup(&audioConsumerQueue, 1);
+ }
+
int i = 0;
primaryBufferPos = 0;
@@ -378,9 +401,7 @@ static void InitializeAudio(int freq)
/* Create thread Locks to ensure synchronization between callback and processing code */
if (pthread_mutex_init(&(lock.mutex), (pthread_mutexattr_t*) NULL) != 0) goto failure;
if (pthread_cond_init(&(lock.cond), (pthread_condattr_t*) NULL) != 0) goto failure;
- pthread_mutex_lock(&(lock.mutex));
lock.value = lock.limit = SecondaryBufferNbr;
- pthread_mutex_unlock(&(lock.mutex));
/* Engine object */
SLresult result = slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL);
@@ -437,6 +458,10 @@ static void InitializeAudio(int freq)
result = (*playerPlay)->SetPlayState(playerPlay, SL_PLAYSTATE_PLAYING);
if(result != SL_RESULT_SUCCESS) goto failure;
+ thread_queue_init(&audioConsumerQueue);
+ shutdown = 0;
+ pthread_create( &audioConsumerThread, NULL, audioConsumer, NULL);
+
return;
failure:
@@ -733,6 +758,7 @@ EXPORT m64p_error CALL PluginStartup(m64p_dynlib_handle CoreLibHandle, void *Con
ConfigSaveSection("Audio-OpenSLES");
l_PluginInit = 1;
+
return M64ERR_SUCCESS;
}
@@ -794,6 +820,7 @@ EXPORT void CALL AiDacrateChanged( int SystemType )
f = 48628316 / (*AudioInfo.AI_DACRATE_REG + 1);
break;
}
+
InitializeAudio(f);
}
@@ -807,39 +834,75 @@ EXPORT void CALL AiLenChanged(void)
unsigned int LenReg = *AudioInfo.AI_LEN_REG;
unsigned char * p = AudioInfo.RDRAM + (*AudioInfo.AI_DRAM_ADDR_REG & 0xFFFFFF);
-
- if (primaryBufferPos + LenReg < primaryBufferBytes)
- {
- unsigned int i;
- for ( i = 0 ; i < LenReg ; i += 4 )
- {
- if(SwapChannels == 0)
- {
- /* Left channel */
- primaryBuffer[ primaryBufferPos + i ] = p[ i + 2 ];
- primaryBuffer[ primaryBufferPos + i + 1 ] = p[ i + 3 ];
-
- /* Right channel */
- primaryBuffer[ primaryBufferPos + i + 2 ] = p[ i ];
- primaryBuffer[ primaryBufferPos + i + 3 ] = p[ i + 1 ];
- }
- else
- {
- /* Left channel */
- primaryBuffer[ primaryBufferPos + i ] = p[ i ];
- primaryBuffer[ primaryBufferPos + i + 1 ] = p[ i + 1 ];
+ queueData* theQueueData = malloc(sizeof(queueData));
+ theQueueData->data = malloc(LenReg);
+ theQueueData->lenght = LenReg;
+
+ memcpy(theQueueData->data, p, LenReg);
+
+ thread_queue_add(&audioConsumerQueue, theQueueData, 0);
+}
+
+void* audioConsumer(void* param)
+{
+
+ while(!shutdown)
+ {
+ struct timespec waitTime;
+ waitTime.tv_sec = 1;
+ waitTime.tv_nsec = 0;
+
+ struct threadmsg msg;
+ int result = thread_queue_get(&audioConsumerQueue, &waitTime, &msg);
+
+ if( result != ETIMEDOUT )
+ {
+ queueData* theQueueData = msg.data;
+ processAudio(theQueueData->data, theQueueData->lenght);
+ free(theQueueData->data);
+ free(msg.data);
+ }
+ }
+
+ return 0;
+}
+
+void processAudio(const unsigned char* buffer, int length)
+{
+ if (primaryBufferPos + length < primaryBufferBytes)
+ {
+ unsigned int i;
+
+ for ( i = 0 ; i < length ; i += 4 )
+ {
+ if(SwapChannels == 0)
+ {
+ /* Left channel */
+ primaryBuffer[ primaryBufferPos + i ] = buffer[ i + 2 ];
+ primaryBuffer[ primaryBufferPos + i + 1 ] = buffer[ i + 3 ];
+
+ /* Right channel */
+ primaryBuffer[ primaryBufferPos + i + 2 ] = buffer[ i ];
+ primaryBuffer[ primaryBufferPos + i + 3 ] = buffer[ i + 1 ];
+ }
+ else
+ {
+ /* Left channel */
+ primaryBuffer[ primaryBufferPos + i ] = buffer[ i ];
+ primaryBuffer[ primaryBufferPos + i + 1 ] = buffer[ i + 1 ];
+
+ /* Right channel */
+ primaryBuffer[ primaryBufferPos + i + 2 ] = buffer[ i + 2];
+ primaryBuffer[ primaryBufferPos + i + 3 ] = buffer[ i + 3 ];
+ }
+ }
+ primaryBufferPos += i;
+ }
+ else
+ DebugMessage(M64MSG_WARNING, "AiLenChanged(): Audio primary buffer overflow.");
+
- /* Right channel */
- primaryBuffer[ primaryBufferPos + i + 2 ] = p[ i + 2];
- primaryBuffer[ primaryBufferPos + i + 3 ] = p[ i + 3 ];
- }
- }
- primaryBufferPos += i;
- }
- else
- DebugMessage(M64MSG_WARNING, "AiLenChanged(): Audio primary buffer overflow.");
-
int newsamplerate = OutputFreq * 100 / speed_factor;
int oldsamplerate = GameFreq;
@@ -852,7 +915,7 @@ EXPORT void CALL AiLenChanged(void)
pthread_cond_wait(&(lock.cond), &(lock.mutex));
--lock.value;
-
+
pthread_mutex_unlock(&(lock.mutex));
// TODO: don't resample if speed_factor = 100 and newsamplerate ~= oldsamplerate
@@ -896,6 +959,7 @@ EXPORT int CALL RomOpen(void)
ReadConfig();
InitializeAudio(GameFreq);
+
return 1;
}
Oops, something went wrong.

0 comments on commit a6236ba

Please sign in to comment.