Jérôme Jouvie 为 FMOD 4+ 编写了一个 JNI 包装器,NativeFmodEx。如果您的 FSB 文件未加密,我认为您可以使用 API 从 FSB 库中提取流数据。
我也尝试编写自己的包装器,但我没有时间通过简单的概念证明。
更新:当然。所以基本上我所做的是使用JNAerator 来包装本机FMODEx 库,然后将生成的胶水代码定位到BridJ 运行时环境。这实际上允许您调用本机 FMOD C 库。
我不确定 Jerome 是否做了类似的事情,或者他是否创建了自己的 JNI 存根来实现相同的结果。您必须查看并阅读他的项目代码。
但本质上,一旦您能够在应用程序中进行 FMOD 调用,您就可以使用 API 随心所欲地进行操作。如果您从 FMOD web site 下载最新的 FMOD studio 或 FMODex SDK,您将找到一个帮助 .chm 文件,其中包含一些 API 文档。
您还应该查看 SDK 中的示例。
以下代码基本上是使用上述策略翻译成 Java 的一个示例。代码对于应用程序来说不是可移植的、健壮的或实际有用的。它确实需要清理,但它仍然说明了这一点。
就像我说的,使用 Jerome 的 SDK 端口应该会更好。
希望对你有帮助。
package net.unsungstories.fmodex;
import net.unsungstories.fmodex.FmodexLibrary.FMOD_CHANNEL;
import net.unsungstories.fmodex.FmodexLibrary.FMOD_SOUND;
import net.unsungstories.fmodex.FmodexLibrary.FMOD_SYSTEM;
import org.apache.log4j.Logger;
import org.bridj.IntValuedEnum;
import org.bridj.Platform;
import org.bridj.Pointer;
import org.junit.Test;
import static org.bridj.Pointer.*;
import static net.unsungstories.fmodex.FmodexLibrary.*;
import static com.google.common.base.Throwables.*;
import static java.lang.String.format;
public class PlaySound {
private static final Logger log = Logger.getLogger(PlaySound.class);
@Test
public void playSound() {
log.info("Test started...");
String soundPath = "./src/test/resources/picus_get_to_finicular_music_0.fsb";
Platform.addEmbeddedLibraryResourceRoot("net/unsungstories/fmodex/");
IntValuedEnum<FMOD_RESULT> result;
Pointer<Pointer<FMOD_SYSTEM>> ppSystem = allocatePointer(FMOD_SYSTEM.class);
Pointer<Pointer<FMOD_SOUND>> ppSound1 = allocatePointer(FMOD_SOUND.class);
Pointer<Integer> pSubSounds = allocateInt();
Pointer<Pointer<FMOD_CHANNEL>> ppChannel = allocatePointer(FMOD_CHANNEL.class);
@SuppressWarnings("unchecked")
Pointer<FMOD_CREATESOUNDEXINFO> soundExInfo = Pointer.NULL;
Pointer<Byte> targetSoundPath = allocateBytes(soundPath.length() + 1);
targetSoundPath.setCString(soundPath);
result = FMOD_System_Create(ppSystem);
result = FMOD_System_Init(ppSystem.get(), 2, FmodexLibrary.FMOD_INIT_NORMAL, Pointer.NULL);
result = FMOD_System_CreateSound(ppSystem.get(), targetSoundPath, FMOD_HARDWARE, soundExInfo, ppSound1);
result = FMOD_Sound_GetNumSubSounds(ppSound1.get(), pSubSounds);
try {
Pointer<Integer> pChanelPlaying = allocateInt();
for (int k = 0; k < pSubSounds.get(); k++) {
Pointer<Pointer<FMOD_SOUND>> ppSubSound = allocatePointer(FMOD_SOUND.class);
result = FMOD_Sound_GetSubSound(ppSound1.get(), k, ppSubSound);
result = FMOD_System_PlaySound(ppSystem.get(), FMOD_CHANNELINDEX.FMOD_CHANNEL_FREE, ppSubSound.get(), 0, ppChannel);
FMOD_Channel_IsPlaying(ppChannel.get(), pChanelPlaying);
while (ppChannel.getBoolean()) {
log.info("Playing...");
Thread.sleep(1000);
FMOD_Channel_IsPlaying(ppChannel.get(), pChanelPlaying);
}
result = FMOD_Sound_Release(ppSubSound.get());
}
result = FMOD_System_Close(ppSystem.get());
result = FMOD_System_Release(ppSystem.get());
} catch (Exception e) {
log.error(getStackTraceAsString(getRootCause(e)));
}
log.info(format("Finished... %s", result));
}
}
希望这会有所帮助。