【问题标题】:Play .mp3 and a sequence of notes (MIDI) simultaneously in Java在 Java 中同时播放 .mp3 和一系列音符 (MIDI)
【发布时间】:2019-08-18 13:08:55
【问题描述】:

我目前正在开发一个应用程序,用户可以在其中加载 .mp3 文件并输入一系列笔记。用户的目标是将此音符序列与 .mp3 文件的歌曲相匹配。

这需要能够同时播放 .mp3 文件和音符序列。经过一番研究,我发现Java Sound APIJFuge 都可以完成产生一系列音符(MIDI)的工作。 (用户给出的输入)。如here 所述,JLayer 可用于播放 Java 中的 mp3 文件。 (我也可以将 .mp3 转换为 .wav 并使用其他方式播放转换后的 .wav)。

但是,是否可以毫无问题地同时播放此 .mp3 和音符序列,还是我应该先将它们转换为一个文件?

用户应该能够在任何随机时间戳同时播放 .mp3 和他/她的音符序列。最好没有任何延迟,以便用户可以轻松地调整音符以匹配文件的音高。当用户几乎不断地更改音符并重放以检查它是否与音高匹配时,在播放它们之前将它们合并到一个文件中似乎会产生太多开销。

提前致谢!

【问题讨论】:

    标签: java audio mp3 midi


    【解决方案1】:

    Java 支持从多个线程播放。您需要做的就是从一个线程运行 .mp3,然后在另一个并发运行的线程上运行 midi 生成的注释。

    曾经有一些 Linux 系统一次只能处理一个音频源的输出。我不知道这是否仍然是一个问题。

    另一种更精细的可能性可以让您进行现场混音并输出到单行,即使用 AudioInputStream 读取歌曲文件,即时将字节转换为 PCM(例如,转换为从 -1 到1)(或将音频预加载并存储为 PCM),然后将其添加到来自自己动手合成器的 PCM 数据中,然后将其转换回字节并通过 SourceDataLine 输出。

    这很麻烦,你可能不想走那条路,但如果你这样做了,下面是一些信息,可以帮助分解一个可能实现的各个步骤。

    在开源AudioCue(第359行loadURL方法)中可以看到加载.wav数据并将其转换为内部PCM格式。 here 是我制作的通过击键运行的实时 Java 合成器的示例(免费下载)。其中一个声音是一个简单的风琴,它只需添加四个谐波频率的正弦波即可输出 PCM 音频数据。如果您想进入其他形式的合成但更多地参与,则可以制作其他声音。

    (IDK 如何转换来自 MIDI 控制的合成器的数据,除非可以识别 TargetDataLine,并且来自它的数据转换为 PCM,类似于在 AudioCue 源示例中从 AudioInputStream 读取时使用的转换。)

    给定两个 PCM 源,两者可以使用加法实时混合,转换为字节并通过单个 SourceDataLine 输出(参见第 1387 行 convertBufferToAudioBytes 方法)。如果您在贡献者不播放时输入零,则 SourceDataLine 可以无限期地保持运行。 SDL 大部分时间都处于阻塞状态,因为音频数据处理比系统消耗的速率快得多,因此使用的 CPU 很少。

    【讨论】:

    • 感谢您的明确答复。当更多的动态“混合”参与其中时,PCM 确实似乎是一种好方法。我先试试多线程的方式。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-06
    • 1970-01-01
    • 1970-01-01
    • 2013-01-25
    相关资源
    最近更新 更多