ソースを参照

fmod: Fallback to opening file via callbacks if direct doesn't work

Fixes #1002
rdb 5 年 前
コミット
1cc82f47b6
1 ファイル変更50 行追加38 行削除
  1. 50 38
      panda/src/audiotraits/fmodAudioSound.cxx

+ 50 - 38
panda/src/audiotraits/fmodAudioSound.cxx

@@ -123,50 +123,62 @@ FmodAudioSound(AudioManager *manager, VirtualFile *file, bool positional) {
           << "Reading " << _file_name << " into memory (" << sound_info.length
           << " bytes)\n";
       }
+      result =
+        _manager->_system->createSound(name_or_data, flags, &sound_info, &_sound);
+    }
+    else {
+      result = FMOD_ERR_FILE_BAD;
+
+      if (file->get_system_info(info)) {
+        // The file exists on disk (or it's part of a multifile that exists on
+        // disk), so we can have FMod read the file directly.  This is also
+        // safe, because FMod uses its own IO operations that don't involve
+        // Panda, so this can safely happen in an FMod thread.
+        os_filename = info.get_filename().to_os_specific();
+        name_or_data = os_filename.c_str();
+        sound_info.fileoffset = (unsigned int)info.get_start();
+        sound_info.length = (unsigned int)info.get_size();
+        flags |= FMOD_CREATESTREAM;
+        if (fmodAudio_cat.is_debug()) {
+          fmodAudio_cat.debug()
+            << "Streaming " << _file_name << " from disk (" << name_or_data
+            << ", " << sound_info.fileoffset << ", " << sound_info.length << ")\n";
+        }
 
-    } else if (file->get_system_info(info)) {
-      // The file exists on disk (or it's part of a multifile that exists on
-      // disk), so we can have FMod read the file directly.  This is also
-      // safe, because FMod uses its own IO operations that don't involve
-      // Panda, so this can safely happen in an FMod thread.
-      os_filename = info.get_filename().to_os_specific();
-      name_or_data = os_filename.c_str();
-      sound_info.fileoffset = (unsigned int)info.get_start();
-      sound_info.length = (unsigned int)info.get_size();
-      flags |= FMOD_CREATESTREAM;
-      if (fmodAudio_cat.is_debug()) {
-        fmodAudio_cat.debug()
-          << "Streaming " << _file_name << " from disk (" << name_or_data
-          << ", " << sound_info.fileoffset << ", " << sound_info.length << ")\n";
+        result =
+          _manager->_system->createSound(name_or_data, flags, &sound_info, &_sound);
       }
 
-    } else {
-#if defined(HAVE_THREADS) && !defined(SIMPLE_THREADS)
-      // Otherwise, if the Panda threading system is compiled in, we can
-      // assign callbacks to read the file through the VFS.
-      name_or_data = (const char *)file;
-      sound_info.length = (unsigned int)info.get_size();
-      sound_info.useropen = open_callback;
-      sound_info.userclose = close_callback;
-      sound_info.userread = read_callback;
-      sound_info.userseek = seek_callback;
-      flags |= FMOD_CREATESTREAM;
-      if (fmodAudio_cat.is_debug()) {
-        fmodAudio_cat.debug()
-          << "Streaming " << _file_name << " from disk using callbacks\n";
-      }
+      // If FMOD can't directly read the file (eg. if Panda is locking it for
+      // write, or it's compressed) we have to use the callback interface.
+      if (result == FMOD_ERR_FILE_BAD) {
+  #if defined(HAVE_THREADS) && !defined(SIMPLE_THREADS)
+        // Otherwise, if the Panda threading system is compiled in, we can
+        // assign callbacks to read the file through the VFS.
+        name_or_data = (const char *)file;
+        sound_info.fileoffset = 0;
+        sound_info.length = (unsigned int)info.get_size();
+        sound_info.useropen = open_callback;
+        sound_info.userclose = close_callback;
+        sound_info.userread = read_callback;
+        sound_info.userseek = seek_callback;
+        flags |= FMOD_CREATESTREAM;
+        if (fmodAudio_cat.is_debug()) {
+          fmodAudio_cat.debug()
+            << "Streaming " << _file_name << " from disk using callbacks\n";
+        }
+        result =
+          _manager->_system->createSound(name_or_data, flags, &sound_info, &_sound);
 
-#else  // HAVE_THREADS && !SIMPLE_THREADS
-      // Without threads, we can't safely read this file.
-      name_or_data = "";
+  #else  // HAVE_THREADS && !SIMPLE_THREADS
+        // Without threads, we can't safely read this file.
+        name_or_data = "";
 
-      fmodAudio_cat.warning()
-        << "Cannot stream " << _file_name << "; file is not literally on disk.\n";
-#endif
+        fmodAudio_cat.warning()
+          << "Cannot stream " << _file_name << "; file is not literally on disk.\n";
+  #endif
+      }
     }
-
-    result =
-      _manager->_system->createSound(name_or_data, flags, &sound_info, &_sound);
   }
 
   if (result != FMOD_OK) {