Tremor decoder now working on Android

* fixed issue where FileDesc_read() would cause a stack overflow
 * fixed incorrect NativeVorbisFile field values
 * properly indicate that streaming is not supported yet
experimental
shadowislord 10 years ago
parent 0c83407f99
commit ba91da8db4
  1. 22
      jme3-android-native/src/native/jme_decode/com_jme3_audio_plugins_NativeVorbisFile.c
  2. 42
      jme3-android/src/main/java/com/jme3/audio/plugins/NativeVorbisLoader.java

@ -1,6 +1,8 @@
#include <unistd.h> #include <unistd.h>
#include <stdlib.h> #include <stdlib.h>
#include <errno.h> #include <errno.h>
#define LIMIT_TO_64kHz
#include "Tremor/ivorbisfile.h" #include "Tremor/ivorbisfile.h"
#include "com_jme3_audio_plugins_NativeVorbisFile.h" #include "com_jme3_audio_plugins_NativeVorbisFile.h"
@ -31,12 +33,8 @@ static size_t FileDesc_read(void *ptr, size_t size, size_t nmemb, void *datasour
FileDescWrapper* wrapper = (FileDescWrapper*)datasource; FileDescWrapper* wrapper = (FileDescWrapper*)datasource;
int req_size = size * nmemb; int req_size = size * nmemb;
int to_read = req_size; int remaining = wrapper->end - wrapper->current;
int to_read = remaining < req_size ? remaining : req_size;
if (wrapper->end - wrapper->current > req_size)
{
to_read = wrapper->end - wrapper->current;
}
if (to_read <= 0) if (to_read <= 0)
{ {
@ -208,9 +206,17 @@ JNIEXPORT void JNICALL Java_com_jme3_audio_plugins_NativeVorbisFile_open
jobject ovfBuf = (*env)->NewDirectByteBuffer(env, ovf, sizeof(OggVorbis_File)); jobject ovfBuf = (*env)->NewDirectByteBuffer(env, ovf, sizeof(OggVorbis_File));
vorbis_info* info = ov_info(ovf, -1); vorbis_info* info = ov_info(ovf, -1);
jint total_bytes = ov_pcm_total(ovf, -1);
// total # of bytes = total samples * bytes per sample * channels
int total_samples = ov_pcm_total(ovf, -1);
jint total_bytes = total_samples * 2 * info->channels;
jboolean seekable = ov_seekable(ovf) != 0; jboolean seekable = ov_seekable(ovf) != 0;
jfloat duration = (jfloat) ov_time_total(ovf, -1);
// duration = millis / 1000
long timeMillis = ov_time_total(ovf, -1);
double timeSeconds = ((double)timeMillis) / 1000.0;
jfloat duration = (jfloat) timeSeconds;
(*env)->SetObjectField(env, nvf, nvf_field_ovf, ovfBuf); (*env)->SetObjectField(env, nvf, nvf_field_ovf, ovfBuf);
(*env)->SetBooleanField(env, nvf, nvf_field_seekable, seekable); (*env)->SetBooleanField(env, nvf, nvf_field_seekable, seekable);

@ -52,6 +52,30 @@ public class NativeVorbisLoader implements AssetLoader {
} }
} }
private static AudioBuffer loadBuffer(AssetInfo assetInfo) throws IOException {
AndroidAssetInfo aai = (AndroidAssetInfo) assetInfo;
AssetFileDescriptor afd = null;
NativeVorbisFile file = null;
try {
afd = aai.openFileDescriptor();
int fd = afd.getParcelFileDescriptor().getFd();
file = new NativeVorbisFile(fd, afd.getStartOffset(), afd.getLength());
ByteBuffer data = BufferUtils.createByteBuffer(file.totalBytes);
file.readFully(data);
AudioBuffer ab = new AudioBuffer();
ab.setupFormat(file.channels, 16, file.sampleRate);
ab.updateData(data);
return ab;
} finally {
if (file != null) {
file.close();
}
if (afd != null) {
afd.close();
}
}
}
@Override @Override
public Object load(AssetInfo assetInfo) throws IOException { public Object load(AssetInfo assetInfo) throws IOException {
AudioKey key = (AudioKey) assetInfo.getKey(); AudioKey key = (AudioKey) assetInfo.getKey();
@ -61,18 +85,10 @@ public class NativeVorbisLoader implements AssetLoader {
"Android's assets directory"); "Android's assets directory");
} }
AndroidAssetInfo aai = (AndroidAssetInfo) assetInfo; if (key.isStream()) {
AssetFileDescriptor afd = aai.openFileDescriptor(); throw new UnsupportedOperationException("Not supported yet. Come again.");
int fd = afd.getParcelFileDescriptor().getFd(); } else {
return loadBuffer(assetInfo);
NativeVorbisFile file = new NativeVorbisFile(fd, afd.getStartOffset(), }
afd.getLength());
ByteBuffer data = BufferUtils.createByteBuffer(file.totalBytes);
file.readFully(data);
AudioBuffer ab = new AudioBuffer();
ab.setupFormat(file.channels, 16, file.sampleRate);
ab.updateData(data);
return ab;
} }
} }
Loading…
Cancel
Save