diff --git a/android/JackOpenSLESDriver.cpp b/android/JackOpenSLESDriver.cpp index f4e8608a..8f863a46 100644 --- a/android/JackOpenSLESDriver.cpp +++ b/android/JackOpenSLESDriver.cpp @@ -30,7 +30,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include #include -#include #include "opensl_io.h" #define JACK_OPENSLES_DEFAULT_SAMPLERATE 48000 diff --git a/android/opensl_io.c b/android/opensl_io.c index 38b6ec0c..4a2c7ad8 100644 --- a/android/opensl_io.c +++ b/android/opensl_io.c @@ -28,6 +28,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "opensl_io.h" +#include +#include //#define CONV16BIT 32768 //#define CONVMYFLT (1./32768.) #define CONV16BIT 32640 @@ -116,12 +118,12 @@ static SLresult openSLPlayOpen(OPENSL_STREAM *p) const SLInterfaceID ids[] = {SL_IID_VOLUME}; const SLboolean req[] = {SL_BOOLEAN_FALSE}; result = (*p->engineEngine)->CreateOutputMix(p->engineEngine, &(p->outputMixObject), 1, ids, req); - if(result != SL_RESULT_SUCCESS) goto end_openaudio; + if(result != SL_RESULT_SUCCESS) return result; // realize the output mix result = (*p->outputMixObject)->Realize(p->outputMixObject, SL_BOOLEAN_FALSE); - int speakers; + SLuint32 speakers; if(channels > 1) speakers = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT; else speakers = SL_SPEAKER_FRONT_CENTER; @@ -225,7 +227,7 @@ static SLresult openSLRecOpen(OPENSL_STREAM *p){ SLDataSource audioSrc = {&loc_dev, NULL}; // configure audio sink - int speakers; + SLuint32 speakers; if(channels > 1) speakers = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT; else speakers = SL_SPEAKER_FRONT_CENTER; @@ -316,7 +318,11 @@ OPENSL_STREAM *android_OpenAudioDevice(int sr, int inchannels, int outchannels, p->outchannels = outchannels; p->sr = sr; p->inlock = createThreadLock(); + if (p->inlock == NULL) + return NULL; p->outlock = createThreadLock(); + if (p->outlock == NULL) + return NULL; if((p->outBufSamples = bufferframes*outchannels) != 0) { if((p->outputBuffer[0] = (short *) calloc(p->outBufSamples, sizeof(short))) == NULL || @@ -336,6 +342,10 @@ OPENSL_STREAM *android_OpenAudioDevice(int sr, int inchannels, int outchannels, p->currentInputIndex = 0; p->currentOutputBuffer = 0; + p->outputBufferSize[0] = 0; + p->outputBufferSize[1] = 0; + p->inputBufferSize[0] = 0; + p->inputBufferSize[1] = 0; p->currentInputIndex = p->inBufSamples; p->currentInputBuffer = 0; @@ -358,6 +368,17 @@ OPENSL_STREAM *android_OpenAudioDevice(int sr, int inchannels, int outchannels, notifyThreadLock(p->inlock); p->time = 0.; + + if (p->bqPlayerBufferQueue) + (*p->bqPlayerBufferQueue)->Enqueue(p->bqPlayerBufferQueue, + p->outputBuffer[0], p->outBufSamples*sizeof(short)); + + if (p->recorderBufferQueue) + (*p->recorderBufferQueue)->Enqueue(p->recorderBufferQueue, + p->inputBuffer[0], p->inBufSamples*sizeof(short)); + + + return p; } @@ -414,39 +435,66 @@ double android_GetTimestamp(OPENSL_STREAM *p){ void bqRecorderCallback(SLAndroidSimpleBufferQueueItf bq, void *context) { OPENSL_STREAM *p = (OPENSL_STREAM *) context; + + while ((p->inputBufferSize[0] > 0) && (p->inputBufferSize[1] > 0)) + usleep(1000); + + p->currentInputBuffer = (p->currentInputBuffer ? 0 : 1); + int queueInputBuffer = (p->currentInputBuffer ? 0 : 1); + int size = p->inBufSamples; + short *inBuffer = p->inputBuffer[queueInputBuffer]; + + (*p->recorderBufferQueue)->Enqueue(p->recorderBufferQueue, + inBuffer, size * sizeof(short)); + + p->inputBufferSize[queueInputBuffer] = size; notifyThreadLock(p->inlock); } // gets a buffer of size samples from the device int android_AudioIn(OPENSL_STREAM *p,float *buffer,int size){ + short *inBuffer; int i, bufsamps, index; if(p == NULL) return 0; bufsamps = p->inBufSamples; + if(bufsamps == 0) return 0; - index = p->currentInputIndex; + if (size > bufsamps) return 0; + if (p->inputBufferSize[p->currentInputBuffer] == 0) + waitThreadLock(p->inlock); + + index = 0; inBuffer = p->inputBuffer[p->currentInputBuffer]; + for(i=0; i < size; i++){ - if (index >= bufsamps) { - waitThreadLock(p->inlock); - (*p->recorderBufferQueue)->Enqueue(p->recorderBufferQueue, - inBuffer,bufsamps*sizeof(short)); - p->currentInputBuffer = (p->currentInputBuffer ? 0 : 1); - index = 0; - inBuffer = p->inputBuffer[p->currentInputBuffer]; - } buffer[i] = (float) inBuffer[index++]*CONVMYFLT; } - p->currentInputIndex = index; + + p->inputBufferSize[p->currentInputBuffer] = 0; if(p->outchannels == 0) p->time += (double) size/(p->sr*p->inchannels); - return i; + + return size; } // this callback handler is called every time a buffer finishes playing void bqPlayerCallback(SLAndroidSimpleBufferQueueItf bq, void *context) { OPENSL_STREAM *p = (OPENSL_STREAM *) context; + + while ((p->outputBufferSize[0] == 0) && (p->outputBufferSize[1] == 0)) + usleep(1000); + + p->currentOutputBuffer = (p->currentOutputBuffer ? 0 : 1); + int queueOutputBuffer = (p->currentOutputBuffer ? 0 : 1); + int size = p->outputBufferSize[queueOutputBuffer]; + short *outBuffer = p->outputBuffer[queueOutputBuffer]; + + (*p->bqPlayerBufferQueue)->Enqueue(p->bqPlayerBufferQueue, + outBuffer, size * sizeof(short)); + + p->outputBufferSize[queueOutputBuffer] = 0; notifyThreadLock(p->outlock); } @@ -457,24 +505,26 @@ int android_AudioOut(OPENSL_STREAM *p, float *buffer,int size){ int i, bufsamps, index; if(p == NULL) return 0; bufsamps = p->outBufSamples; + if(bufsamps == 0) return 0; - index = p->currentOutputIndex; + if (size > bufsamps) return 0; + + + if (p->outputBufferSize[p->currentOutputBuffer] != 0) + waitThreadLock(p->outlock); + + index = 0; outBuffer = p->outputBuffer[p->currentOutputBuffer]; + for(i=0; i < size; i++){ outBuffer[index++] = (short) (buffer[i]*CONV16BIT); - if (index >= p->outBufSamples) { - waitThreadLock(p->outlock); - (*p->bqPlayerBufferQueue)->Enqueue(p->bqPlayerBufferQueue, - outBuffer,bufsamps*sizeof(short)); - p->currentOutputBuffer = (p->currentOutputBuffer ? 0 : 1); - index = 0; - outBuffer = p->outputBuffer[p->currentOutputBuffer]; - } } - p->currentOutputIndex = index; + + p->outputBufferSize[p->currentOutputBuffer] = size; + p->time += (double) size/(p->sr*p->outchannels); - return i; + return size; } //---------------------------------------------------------------------- @@ -507,12 +557,12 @@ int waitThreadLock(void *lock) int retval = 0; p = (threadLock*) lock; pthread_mutex_lock(&(p->m)); + p->s = (unsigned char) 0; while (!p->s) { pthread_cond_wait(&(p->c), &(p->m)); } - p->s = (unsigned char) 0; pthread_mutex_unlock(&(p->m)); - return NULL; + return retval; } void notifyThreadLock(void *lock) diff --git a/android/opensl_io.h b/android/opensl_io.h index 501f0361..fcb7c6a7 100644 --- a/android/opensl_io.h +++ b/android/opensl_io.h @@ -72,10 +72,12 @@ typedef struct opensl_stream { // current buffer half (0, 1) int currentOutputBuffer; int currentInputBuffer; - + // buffers short *outputBuffer[2]; short *inputBuffer[2]; + int outputBufferSize[2]; + int inputBufferSize[2]; // size of buffers int outBufSamples;