gpt4 book ai didi

java - 在 Java 中使用/读取 FMOD (.fsb) 文件

转载 作者:太空宇宙 更新时间:2023-11-04 07:09:02 28 4
gpt4 key购买 nike

大家好。我目前正在开发一个应用程序,该应用程序应该播放 FMOD 数据库中的音乐文件。目前,它通过将文件提取(使用运行时和名为“fsbextract.exe”( link )的外部程序)作为 MP3 然后播放它们来实现。我对此表示同意,但我现在也想编辑/替换 .fsb 文件中的文件。所以我的问题是:我可以以某种方式直接访问其中的 MP3 文件而不解压它们吗?我在互联网上搜索了类似的内容,但找不到任何帮助。

作为引用,以下是我可以从 fsbextract 中获取的一些信息:

文件 ID 为 |FSB4> |版本是4.0 |条目数 7412

全局标志:

0x40 | FMOD_FSB_SOURCE_MPEG_PADDED4 | FMOD_FSB_SOURCE_MPEG_PADDED4 MPEG 帧对齐到最近的 4 字节,多 channel 为 16 字节(使用帧验证选项)

从 fsb 文件中的第一个(索引 0)文件开始:格式:MP3 (85)采样率:44100Hz channel :单声道持续时间:01.541比特率:160,62 kbit/s位数/样本 3.64

示例模式标志 [0x10000200]0x200 | 0x200 FSOUND_MPEG |样本以 MPEG 格式存储0x10000000 | FSOUND_MPEG_LAYER3 | FSOUND_MPEG_LAYER3 |样本以 MPEG Layer 3 格式存储

我希望有人比我更了解,但提前致谢玛伦蒂尤

最佳答案

Jérôme Jouvie 为 FMOD 4+ 编写了一个 JNI 包装器,NativeFmodEx 。如果您的 FSB 文件未加密,我认为您可以使用 API 从 FSB 库中提取流数据。

我也尝试编写自己的包装器,但我没有时间完成简单的概念证明。

更新:当然。所以基本上我所做的就是使用 JNAerator包装 native FMODex 库,然后将生成的粘合代码定位到 BridJ运行环境。这本质上允许您调用 native FMOD C 库。

我不太确定 Jerome 是否做了类似的事情,或者他是否创建了自己的 JNI stub 来实现相同的结果。您必须查看并阅读他的项目代码。

但本质上,一旦您能够在应用程序内进行 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));
}
}

希望这有帮助。

关于java - 在 Java 中使用/读取 FMOD (.fsb) 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20924689/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com