summaryrefslogtreecommitdiff
path: root/LoopbackApp/app/src/main/jni
diff options
context:
space:
mode:
authorRicardo Garcia <rago@google.com>2015-04-02 14:58:29 -0700
committerRicardo Garcia <rago@google.com>2015-04-02 15:04:24 -0700
commite1b0d76f5597f735509e48e732e3efa26ea9fe0b (patch)
tree7108e4c96aa47b7cb72466cd8097bf234bf28e49 /LoopbackApp/app/src/main/jni
parent6c27b1100b1db706d824c78f8ad1311f08ef23f2 (diff)
downloaddrrickorang-e1b0d76f5597f735509e48e732e3efa26ea9fe0b.tar.gz
Bugfixing for older Android versions
Fixing some race conditions that became problematic on older android versions. Instrumented JNI code with debug/log messages. Reduced memory footprint of JNI test by directly using the actual buffer of interest.
Diffstat (limited to 'LoopbackApp/app/src/main/jni')
-rw-r--r--LoopbackApp/app/src/main/jni/jni_sles.c24
-rw-r--r--LoopbackApp/app/src/main/jni/jni_sles.h2
-rw-r--r--LoopbackApp/app/src/main/jni/sles.cpp72
-rw-r--r--LoopbackApp/app/src/main/jni/sles.h3
4 files changed, 94 insertions, 7 deletions
diff --git a/LoopbackApp/app/src/main/jni/jni_sles.c b/LoopbackApp/app/src/main/jni/jni_sles.c
index 02e69dc..9d12a1c 100644
--- a/LoopbackApp/app/src/main/jni/jni_sles.c
+++ b/LoopbackApp/app/src/main/jni/jni_sles.c
@@ -24,21 +24,35 @@
JNIEXPORT jlong JNICALL Java_org_drrickorang_loopback_NativeAudioThread_slesInit
(JNIEnv *env __unused, jobject obj __unused, jint samplingRate, jint frameCount) {
- sles_data * pSles;
- slesInit(&pSles, samplingRate, frameCount);
+ sles_data * pSles = NULL;
+
+ if( slesInit(&pSles, samplingRate, frameCount) != SLES_FAIL ) {
+
+ return (long)pSles;
+ }
// FIXME This should be stored as a (long) field in the object,
// so that incorrect Java code could not synthesize a bad sles pointer.
- return (long)pSles;
+ return 0;
}
JNIEXPORT jint JNICALL Java_org_drrickorang_loopback_NativeAudioThread_slesProcessNext
-(JNIEnv *env __unused, jobject obj __unused, jlong sles, jdoubleArray samplesArray) {
+(JNIEnv *env __unused, jobject obj __unused, jlong sles, jdoubleArray samplesArray, jlong offset) {
sles_data * pSles= (sles_data*) sles;
long maxSamples = (*env)->GetArrayLength(env, samplesArray);
double *pSamples = (*env)->GetDoubleArrayElements(env, samplesArray,0);
- int samplesRead = slesProcessNext(pSles, pSamples, maxSamples);
+ long availableSamples = maxSamples-offset;
+ double *pCurrentSample = pSamples+offset;
+
+
+
+ //int samplesRead = slesProcessNext(pSles, pSamples, maxSamples);
+
+ SLES_PRINTF("jni slesProcessNext pSles:%p, currentSample %p, availableSamples %d ", pSles, pCurrentSample, availableSamples);
+
+
+ int samplesRead = slesProcessNext(pSles, pCurrentSample, availableSamples);
return samplesRead;
}
diff --git a/LoopbackApp/app/src/main/jni/jni_sles.h b/LoopbackApp/app/src/main/jni/jni_sles.h
index 56e7bb6..8be992a 100644
--- a/LoopbackApp/app/src/main/jni/jni_sles.h
+++ b/LoopbackApp/app/src/main/jni/jni_sles.h
@@ -29,7 +29,7 @@ JNIEXPORT jlong JNICALL Java_org_drrickorang_loopback_NativeAudioThread_slesInit
(JNIEnv *, jobject, jint, jint );
JNIEXPORT jint JNICALL Java_org_drrickorang_loopback_NativeAudioThread_slesProcessNext
- (JNIEnv *, jobject , jlong, jdoubleArray );
+ (JNIEnv *, jobject , jlong, jdoubleArray, jlong );
JNIEXPORT jint JNICALL Java_org_drrickorang_loopback_NativeAudioThread_slesDestroy
(JNIEnv *, jobject , jlong );
diff --git a/LoopbackApp/app/src/main/jni/sles.cpp b/LoopbackApp/app/src/main/jni/sles.cpp
index 0290099..06efe44 100644
--- a/LoopbackApp/app/src/main/jni/sles.cpp
+++ b/LoopbackApp/app/src/main/jni/sles.cpp
@@ -40,10 +40,15 @@ int slesInit(sles_data ** ppSles, int samplingRate, int frameCount) {
int status = SLES_FAIL;
if (ppSles != NULL) {
sles_data * pSles = (sles_data*)malloc( sizeof (sles_data));
+
+ SLES_PRINTF("malloc %d bytes at %p",sizeof(sles_data), pSles);
+ //__android_log_print(ANDROID_LOG_INFO, "sles_jni", "malloc %d bytes at %p",sizeof(sles_data), pSles);//Or ANDROID_LOG_INFO, ...
*ppSles = pSles;
if (pSles != NULL)
{
+ SLES_PRINTF("creating server. Sampling rate =%d, frame count = %d",samplingRate, frameCount);
status = slesCreateServer(pSles, samplingRate, frameCount);
+ SLES_PRINTF("slesCreateServer =%d",status);
}
}
return status;
@@ -70,9 +75,11 @@ static void recorderCallback(SLAndroidSimpleBufferQueueItf caller __unused, void
if (pSles != NULL) {
+
SLresult result;
pthread_mutex_lock(&(pSles->mutex));
+ //ee SLES_PRINTF("<R");
// We should only be called when a recording buffer is done
assert(pSles->rxFront <= pSles->rxBufCount);
@@ -118,6 +125,7 @@ static void recorderCallback(SLAndroidSimpleBufferQueueItf caller __unused, void
+ //ee SLES_PRINTF("r>");
pthread_mutex_unlock(&(pSles->mutex));
} //pSles not null
@@ -132,6 +140,7 @@ static void playerCallback(SLBufferQueueItf caller __unused, void *context) {
SLresult result;
pthread_mutex_lock(&(pSles->mutex));
+ //ee SLES_PRINTF("<P");
// Get the buffer that just finished playing
assert(pSles->txFront <= pSles->txBufCount);
@@ -182,7 +191,7 @@ static void playerCallback(SLBufferQueueItf caller __unused, void *context) {
pSles->txRear = txRearNext;
-
+ //ee SLES_PRINTF("p>");
pthread_mutex_unlock(&(pSles->mutex));
} //pSles not null
@@ -363,6 +372,8 @@ int slesCreateServer(sles_data *pSles, int samplingRate, int frameCount) {
if (SL_RESULT_CONTENT_UNSUPPORTED == result) {
fprintf(stderr, "Could not create audio player (result %x), check sample rate\n",
result);
+ SLES_PRINTF("ERROR: Could not create audio player (result %x), check sample rate\n",
+ result);
goto cleanup;
}
ASSERT_EQ(SL_RESULT_SUCCESS, result);
@@ -429,6 +440,9 @@ int slesCreateServer(sles_data *pSles, int samplingRate, int frameCount) {
fprintf(stderr, "Could not create audio recorder (result %x), "
"check sample rate and channel count\n", result);
status = SLES_FAIL;
+
+ SLES_PRINTF("ERROR: Could not create audio recorder (result %x), "
+ "check sample rate and channel count\n", result);
goto cleanup;
}
}
@@ -479,6 +493,8 @@ int slesCreateServer(sles_data *pSles, int samplingRate, int frameCount) {
status = SLES_SUCCESS;
cleanup:
+ SLES_PRINTF("Finished initialization with status: %d", status);
+
int xx =1;
}
@@ -488,6 +504,8 @@ int slesCreateServer(sles_data *pSles, int samplingRate, int frameCount) {
int slesProcessNext(sles_data *pSles, double *pSamples, long maxSamples) {
//int status = SLES_FAIL;
+ SLES_PRINTF("slesProcessNext: pSles = %p, currentSample: %p, maxSamples = %d", pSles, pSamples, maxSamples);
+
int samplesRead = 0;
int currentSample = 0;
@@ -537,32 +555,84 @@ int slesProcessNext(sles_data *pSles, double *pSamples, long maxSamples) {
result = (*(pSles->recorderBufferQueue))->GetState(pSles->recorderBufferQueue,
&recorderBQState);
ASSERT_EQ(SL_RESULT_SUCCESS, result);
+
+ SLES_PRINTF("End of slesProcessNext: pSles = %p, samplesRead = %d, maxSamples= %d", pSles, samplesRead, maxSamples);
}
return samplesRead;
}
int slesDestroyServer(sles_data *pSles) {
int status = SLES_FAIL;
+ SLES_PRINTF("Start slesDestroyServer: pSles = %p", pSles);
+
if (pSles != NULL) {
+
+
+
+ if (NULL != pSles->playerObject) {
+
+ SLES_PRINTF("stopping player...");
+ SLPlayItf playerPlay;
+ SLresult result = (*(pSles->playerObject))->GetInterface(pSles->playerObject, SL_IID_PLAY,
+ &playerPlay);
+
+ ASSERT_EQ(SL_RESULT_SUCCESS, result);
+
+ //stop player and recorder if they exist
+ result = (*playerPlay)->SetPlayState(playerPlay, SL_PLAYSTATE_STOPPED);
+ ASSERT_EQ(SL_RESULT_SUCCESS, result);
+ }
+
+ if (NULL != pSles->recorderObject) {
+
+
+ SLES_PRINTF("stopping recorder...");
+ SLRecordItf recorderRecord;
+ SLresult result = (*(pSles->recorderObject))->GetInterface(pSles->recorderObject, SL_IID_RECORD,
+ &recorderRecord);
+ ASSERT_EQ(SL_RESULT_SUCCESS, result);
+
+
+ result = (*recorderRecord)->SetRecordState(recorderRecord, SL_RECORDSTATE_STOPPED);
+ ASSERT_EQ(SL_RESULT_SUCCESS, result);
+ }
+
+ usleep(1000);
+
+
audio_utils_fifo_deinit(&(pSles->fifo));
delete[] pSles->fifoBuffer;
+ SLES_PRINTF("slesDestroyServer 2");
+
// if (sndfile != NULL) {
audio_utils_fifo_deinit(&(pSles->fifo2));
delete[] pSles->fifo2Buffer;
+
+ SLES_PRINTF("slesDestroyServer 3");
+
// sf_close(sndfile);
// }
if (NULL != pSles->playerObject) {
(*(pSles->playerObject))->Destroy(pSles->playerObject);
}
+
+ SLES_PRINTF("slesDestroyServer 4");
+
if (NULL != pSles->recorderObject) {
(*(pSles->recorderObject))->Destroy(pSles->recorderObject);
}
+
+ SLES_PRINTF("slesDestroyServer 5");
+
(*(pSles->outputmixObject))->Destroy(pSles->outputmixObject);
+ SLES_PRINTF("slesDestroyServer 6");
(*(pSles->engineObject))->Destroy(pSles->engineObject);
+ SLES_PRINTF("slesDestroyServer 7");
}
+ SLES_PRINTF("End slesDestroyServer: status = %d", status);
return status;
}
diff --git a/LoopbackApp/app/src/main/jni/sles.h b/LoopbackApp/app/src/main/jni/sles.h
index 5e41b15..15f6f2e 100644
--- a/LoopbackApp/app/src/main/jni/sles.h
+++ b/LoopbackApp/app/src/main/jni/sles.h
@@ -17,11 +17,14 @@
#include <SLES/OpenSLES.h>
#include <SLES/OpenSLES_Android.h>
#include <pthread.h>
+#include <android/log.h>
#ifndef _Included_org_drrickorang_loopback_sles
#define _Included_org_drrickorang_loopback_sles
//struct audio_utils_fifo;
+#define SLES_PRINTF(...) __android_log_print(ANDROID_LOG_INFO, "sles_jni", __VA_ARGS__);
+
#ifdef __cplusplus
extern "C" {