emrahgunduz emrahgunduz - 5 months ago 27
Android Question

Buffering URI on OpenSL, Android

I have been trying the OpenSL for a few weeks now. I'm trying to access to the buffer while playing a file on sdcard via SL_DATALOCATOR_URI as a source. I want to write a few effects of my own and need the buffer.

Currently in the code, I'm creating two audio players. One is reading the file to buffer, other is writing the buffer to the output. When I'm testing the code with the microphone (recorder), everything is fine. Sound in-out works as expected.

When I switch the recorder with a uri audioplayer, queue goes haywire. Streaming is not listening to thread locks (it occurs async as I understand) and buffer calls are not fired correctly, time flies away.

I've put logs to every method, so the result appears something like this:

V/PDecoder( 1292): Position : 15023
V/PDecoder( 1292): Position : 16044
V/PDecoder( 1292): Position : 17043
V/PDecoder Native PL1( 1292): bqPlayerCallback
V/PDecoder Native PL1( 1292): Notify thread lock
V/PDecoder Native PL1( 1292): android_AudioIn 32768
V/PDecoder Native PL1( 1292): Wait thread lock
V/PDecoder Native PL1( 1292): android_AudioOut 32768
V/PDecoder Native PL1( 1292): android_AudioIn 32768
V/PDecoder Native PL1( 1292): android_AudioOut 32768
V/PDecoder Native PL1( 1292): Wait thread lock
V/PDecoder Native PL1( 1292): bqRecorderCallback
V/PDecoder Native PL1( 1292): Notify thread lock
V/PDecoder( 1708): Position : 18041
V/PDecoder( 1708): Position : 19040
V/PDecoder( 1708): Position : 20038


Seconds fly away before queue callbacks are even fired.

So the question is, how can I correct this problem? Is there a way for audioplayer > buffer > output solution for uri playback? What am I doing wrong? If someone can point me to the right direction, it is greatly appreciated.

The code is a little long for pasting here, so here are the gists


Answer

After loosing myself in the code I gave in the question, decided to write it again, as clean as possible.

I found out that I were not locking the uri player after all. I'm adding the working final code at the end of the answer. The code is good for playing local file or url, but needs to be run in a thread started from java, or you'll lock the gui thread.

PS. The buffer is using stack, so you might want to move it to the heap, and probably save the pointer in the struct. Also, play, pause, destroy methods are not finished. If you want to use the code, you can easily implement these functions.

Bonus. The code also includes a simple way to call java instance methods (without the dreaded *env sent from java part). If you need it, look at JNI_OnLoad, then playStatusCallback() and then callPositionChanged() methods.

The code is a little long for pasting here, so here are the gists