diff --git a/firmware/target/hosted/android/pcm-android.c b/firmware/target/hosted/android/pcm-android.c index ae8e9a2..5a9721c 100644 --- a/firmware/target/hosted/android/pcm-android.c +++ b/firmware/target/hosted/android/pcm-android.c @@ -5,7 +5,7 @@ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * \/ \/ \/ \/ \/ - * $Id$ + * $Id: pcm-android.c 29826 2011-05-05 19:20:58Z bluebrother $ * * Copyright (c) 2010 Thomas Martitz * @@ -23,6 +23,7 @@ #include #define _SYSTEM_WITH_JNI /* for getJavaEnvironment */ #include +#include #include "debug.h" #include "pcm.h" @@ -31,6 +32,8 @@ extern JNIEnv *env_ptr; /* infos about our pcm chunks */ static size_t pcm_data_size; static char *pcm_data_start; +static int audio_locked = 0; +static pthread_mutex_t audio_lock_mutex = PTHREAD_MUTEX_INITIALIZER; /* cache frequently called methods */ static jmethodID play_pause_method; @@ -41,6 +44,20 @@ static jobject RockboxPCM_instance; /* + * mutex lock/unlock wrappers neatness' sake + */ +static inline void lock_audio(void) +{ + pthread_mutex_lock(&audio_lock_mutex); +} + +static inline void unlock_audio(void) +{ + pthread_mutex_unlock(&audio_lock_mutex); +} + + +/* * transfer our raw data into a java array * * a bit of a monster functions, but it should cover all cases to overcome @@ -57,6 +74,8 @@ Java_org_rockbox_RockboxPCM_pcmSamplesToByteArray(JNIEnv *env, jobject this, jbyteArray arr) { + lock_audio(); + (void)this; size_t len; size_t array_size = (*env)->GetArrayLength(env, arr); @@ -76,6 +95,7 @@ Java_org_rockbox_RockboxPCM_pcmSamplesToByteArray(JNIEnv *env, if (pcm_data_size == 0) { DEBUGF("out of data\n"); + unlock_audio(); return; } if (remaining > pcm_data_size) @@ -90,19 +110,26 @@ Java_org_rockbox_RockboxPCM_pcmSamplesToByteArray(JNIEnv *env, goto retry; } else + { (*env)->SetByteArrayRegion(env, arr, offset, remaining, pcm_data_start); + } len = remaining; } pcm_data_start += len; pcm_data_size -= len; + unlock_audio(); } void pcm_play_lock(void) { + if (++audio_locked == 1) + lock_audio(); } void pcm_play_unlock(void) { + if (--audio_locked == 0); + unlock_audio(); } void pcm_dma_apply_settings(void) @@ -168,8 +195,6 @@ void pcm_play_dma_init(void) play_pause_method = e->GetMethodID(env_ptr, RockboxPCM_class, "play_pause", "(Z)V"); set_volume_method = e->GetMethodID(env_ptr, RockboxPCM_class, "set_volume", "(I)V"); stop_method = e->GetMethodID(env_ptr, RockboxPCM_class, "stop", "()V"); - /* get initial pcm data, if any */ - pcm_play_get_more_callback((void*)&pcm_data_start, &pcm_data_size); } void pcm_postinit(void)