oboe
oboe copied to clipboard
How can I read an audio file from res/raw? And from SDCard?
I studied the RhythmGame example and it only works at NDK level using the assets folder. I need to support other ways of file import, like from R.raw and from folder Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
How can I achieve that? Any help?
The solution is read details about the file descriptor and adapt the code to skip de AAsset_openFileDescriptor step.
SDK side (using SD Card):
val path ="${Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)}/file.mp3"
val file = ParcelFileDescriptor.open(File(path), ParcelFileDescriptor.MODE_READ_ONLY)
val fileDescriptor = file.fileDescriptor
val field = fileDescriptor.javaClass.getDeclaredField("descriptor")
field.isAccessible = true
val fileDescriptorId = field.getInt(file.fileDescriptor)
jniCall(fileDescriptorId, file.statSize.toInt(), 0)
SDK side (using res/raw folder)
val file = context.get()!!.resources.openRawResourceFd(rawFileId)
val fileOffset = file.startOffset.toInt()
val fileLength = file.length.toInt()
val fileDescriptor = file.fileDescriptor
val field = fileDescriptor.javaClass.getDeclaredField("descriptor")
field.isAccessible = true
val fileDescriptorId = field.getInt(file.fileDescriptor)
jniCall(fileDescriptorId, fileLength), fileOffset)
NDK side:
Java_package_Player_jniCall(
JNIEnv* env,
jobject __unused,
jint fd,
jint fileLength,
jint fileOffset) {
// Instead of calling NDKExtractor::decode(AAsset *asset, uint8_t *targetData, AudioProperties targetProperties), lets adapt to NDKExtractor::decodeFileDescriptor(int fd, int offset, int length, uint8_t* targetData, AudioProperties targetProperties)
}
NDKExtractor:
int32_t NDKExtractor::decodeFileDescriptor(int fd, int offset, int length, uint8_t* targetData, AudioProperties targetProperties) {
// Ignoring AAsset_openFileDescriptor step...
// Extract the audio frames
AMediaExtractor *extractor = AMediaExtractor_new();
media_status_t amresult = AMediaExtractor_setDataSourceFd(extractor, fd, offset, length);
if (amresult != AMEDIA_OK){
LOGE("Error setting extractor data source, err %d", amresult);
return 0;
}
// ...
I still not tried any solution using the FFMpegExtractor, if anyone could help that would be nice.
You may be able to use ExoPlayer Media3 Transformer to convert an MP3 file or URI to a WAV or PCM.
https://developer.android.com/guide/topics/media/transformer/getting-started