Re: [Op1enSL] File c decoding to arbitratry-sized buffers

20 views
Skip to first unread message

Hyukmin Kwon

unread,
May 12, 2015, 1:44:16 AM5/12/15
to andro...@googlegroups.com

1

  nz 4

On May 10, 2015 3:13 PM, "Domagoj Saric" <dsa...@gmail.com> wrote:

Hi everyone,

I'm trying to implement a simple audio file reader class (which decodes the file on-demand into in-memory raw PCM data):
class file_reader
{
  void open( location );
  void read( buffer );
}

As usual, on iOS this is of course trivial (you just call ExtAudioFileRead() and get the result on the same thread right there and then) while on Android it is an excercise in torture.

There appear to be three (undocumented) requirements:

1) buffer.size() (in the (*pBQ)->Enqueue( pBQ, buffer.begin(), buffer.size() call) cannot be any arbitrary value, it has to be a multiple of the internal block size used by the decoder for the particular type of file opened (e.g. 1152 for MP3 or 1024 for AAC).
If the enqueued buffer is of the wrong size there will be no error or warning in the log, rather the decoder will simply decode a multiple of the block-size and silently discard the data that does not fit in the buffer (or something along those lines - the end effect is that the file plays back too fast/it skips).

2) Between two calls to read() the file_reader object cannot just "do nothing and then simply enqueue a new buffer on the next call to read()", rather it has to block the last slAndroidSimpleBufferQueueCallback and then unblock it after enqueuing a new buffer (in the next read() call) - otherwise, again, the decoder seems to silently decode the file in the background discarding the data when there is no buffer enqueued (the end effect is again that the file plays too fast/it skips).

3) If you want to use the SLPrefetchStatusItf interface (it is not clear, but from the official examples it seems this is the only way to 'reliably' detect errors on file opening/metadata extraction) then at least two buffers have to be enqueued before setting SL_PLAYSTATE_PLAYING as otherwise an assertion failure inside OpenSL (srsly, compiling an OS, a mobile one at that, with assertions enabled!?) crashes your app...

Now, the second and third point "I can live with sort of", but 'how on earth' am I supposed to know which buffer size to use in the most general case (where I don't know the file type in advance, rather the user chooses it)? Even if I can somehow detect which file type was opened (the filename extension is of course not the most reliable mechanism) how can I know the undocumented block size used by the decoder for the given file encoding/container (e.g. what block size must one use for simple uncompresed .wav files)?


--
"What Huxley teaches is that in the age of advanced technology, spiritual devastation is more likely to come from an enemy with a smiling face than from one whose countenance exudes suspicion and hate."
Neil Postman

--
You received this message because you are subscribed to the Google Groups "android-ndk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to android-ndk...@googlegroups.com.
To post to this group, send email to andro...@googlegroups.com.
Visit this group at http://groups.google.com/group/android-ndk.
For more options, visit https://groups.google.com/d/optout.
Reply all
Reply to author
Forward
0 new messages