9

我正在尝试直接从我的 Android 应用程序动态生成一个小的 MP4 音频+视频文件。

我原来的进攻计划:

  1. 用户输入一些基本的歌曲数据(和弦进行等),应用程序构建一个 MIDI 文件。

  2. 系统为每个和弦构建和弦图,并使用 MIDI 阅读器生成与 MIDI 同步的动画帧数组

  3. 将 MIDI 转换为原始 PCM 音频数据<--这个 SO 问题是针对这一点的

  4. 将原始音频应用于动画帧 - 并将音频和视频帧编码为 MP4

  5. 使用标准播放控件向用户提供生成的 MP4 视频。

该应用程序已经根据用户输入(包括速度、乐器、音符等)构建了 MIDI 文件。这部分很容易完成,并且 MIDI 文件正在正确生成。这个 MIDI 可以在 Android 的 MediaPlayer 中正常播放。(步骤1)

通过回读 MIDI 文件并交叉引用序列中每个和弦的静态位图列表,也可以正确创建动画帧。这些帧将成为视频......但一开始将没有音频。(第2步)

如您所见,Android MIDI 延迟问题对我来说并不是什么大问题,因为我没有创建实时合成器应用程序......我只是想将 MIDI 转换为一些可以混合的音频格式到已经定时到原始 MIDI 的视频中。(第 3 步)


我遇到的问题是第 3 步。

我知道我需要使用软件 MIDI 合成器来获取从一系列 MIDI 事件中产生的实际音频输出。但是,如何使其正常工作已成为主要障碍。我不关心生成的音频的精确质量,只是它与人们在使用通用设备(ala Gravis soundfonts 或内置 Sovinox 声音等)的通用 MIDI 样本时所期望的非常匹配。

所以...

  1. Android MIDI 库

  2. 使用 Sonivox EAS 库的 Android Midi 驱动程序

我的第一次尝试是使用上述两个项目......以这样的方式将它们混合在一起,以便 MIDI 文件可以转换为原始 PCM 数据缓冲区......它还没有那么顺利。

midi 库 (1) 使用实时监听器读取 MIDI 文件,并将事件发送到 Midi Driver (2),后者播放板载合成器生成的原始 PCM 数据。

(注意:对驱动程序进行了一些调整,以便存储整个缓冲区并仅在 MIDI 读取器完成后返回。这也意味着整个过程需要与歌曲长度相等的时间来转换它因为我们是实时“听”的。)

我还没有像我希望的那样让它工作。我想让这尽可能简单,如果可能的话,我更喜欢使用开源项目。如果它能够在不依赖实时监听器的情况下做到这一点会更好。


我一直在考虑的其他一些库和工具(但可能有点矫枉过正):

  1. 适用于 Android 的纯数据库

  2. MidiSheetMusic 应用程序(带源)

  3. C++ 中的综合工具包 (STK)

  4. 安卓音乐合成器

  5. 深红软合成器

更多的竞争者(还没有做太多的研究):

jFugue/胆怯/大胆/fluidSynth/cSound/jMusic/JSyn/Gervill/Softonic/Cau​​stic/LibGDX/JetPlayer/OpenSL-ES


我的问题是:

  • 我是否在上述项目中走上正确的道路?我对 MIDI->PCM 转换比较陌生,所以我想确保我没有完全遗漏一些东西。

  • 如果没有,我应该如何将 MIDI 文件转换为某种音频格式,然后可以用于创建 MP4(或任何视频播放格式)?

  • 是否有其他开源项目可能有助于使用 Android 转换 MIDI 2 原始音频波形的任务?

  • 有没有已经为在 Android 上使用而编写的此类任务的示例?(即已经移植用于 Android JNI 等)

我希望我完全错过了一些让这成为一项微不足道的任务的事情......我的假设是这将需要一些严肃的黑客攻击和 JNI 功夫。

如果需要的话,我愿意走艰难的道路。任何和所有的建议将不胜感激。

4

2 回答 2

1

我不是 Android 用户,但我尝试了很多从 MIDI 生成 WAV 文件的方法,而且我对这个任务更满意,使用 FluidSynth,它似​​乎可以作为 Android 的库使用,并且是重点另一个 StackOverflow 问题:Using Fluidsynth to play notes from SoundFonts on Android

你只需要了解声音字体(搜索网络很容易告诉你)并选择一个不太大的好字体(否则你可能会出现内存不足的问题)。

还要检查声音字体是否涵盖了您想要演奏的所有乐器。

于 2015-06-08T04:46:51.160 回答
0

如果您在 JS 或 Node 环境中运行,您应该能够使用 mudcube 的 MIDI.js(或我的 ES6 端口作为 midicube)使用 Player 对象将 MIDI 转换为 webaudio 输出并轻松播放。或者,如果您想保存它,您可以捕获流并将其转换为任意数量的格式(可能包括 mp3,但我从未尝试过)。如果时间不是转换的关键,第二部分应该很容易,但是转换需要 MIDI 的运行时间。应该可以加快播放速度和样本的播放速度,使转换以 2 或 4 倍的速度发生,然后再放慢文件速度,但我没有尝试过。

如果您对库具有较低级别的访问权限,那么 @Hibou57 建议使用 FluidSynth 是最好的。

无论哪种方式,您都需要一些声音字体。Fluid-GM 适用于较低质量但可接受的声音。

于 2022-02-20T11:14:34.713 回答