浏览代码

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

shadowislord 10 年之前
父节点
当前提交
ba91da8db4

+ 14 - 8
jme3-android-native/src/native/jme_decode/com_jme3_audio_plugins_NativeVorbisFile.c

@@ -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;
-    
-    if (wrapper->end - wrapper->current > req_size)
-    {
-        to_read = wrapper->end - wrapper->current;
-    }
+    int remaining = wrapper->end - wrapper->current;
+    int to_read = remaining < req_size ? remaining : req_size;
     
     
     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);

+ 29 - 13
jme3-android/src/main/java/com/jme3/audio/plugins/NativeVorbisLoader.java

@@ -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;
-        AssetFileDescriptor afd = aai.openFileDescriptor();
-        int fd = afd.getParcelFileDescriptor().getFd();
-        
-        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;
+        if (key.isStream()) {
+            throw new UnsupportedOperationException("Not supported yet. Come again.");
+        } else {
+            return loadBuffer(assetInfo);
+        }
     }
     }
 }
 }