在Java中同时播放.mp3和一系列音符(MIDI)

时间:2019-08-18 13:08:55

标签: java audio mp3 midi

我当前正在开发一个应用程序,用户可以在其中加载.mp3文件并输入注释序列。用户的目标是使这些音符序列与.mp3文件的歌曲匹配。

这要求可以同时播放.mp3文件和音符序列。经过一些研究,我发现Java Sound APIJFuge都能完成音符序列(MIDI)的工作。 (用户提供的输入)。如here所述,JLayer可用于播放Java中的mp3文件。 (我也可以将.mp3转换为.wav,并使用另一种方式播放转换后的.wav)。

但是,是否可以同时播放此.mp3和音符序列而没有任何问题,还是应该先将它们转换为一个文件?

用户应该能够同时在任何随机时间戳上播放.mp3及其音符序列。优选地,没有任何延迟,因此用户可以容易地使音符适应文件的音高。当用户几乎不断更改音符并重放以检查音高是否匹配时,在播放它们之前将它们合并到一个文件似乎会产生过多的开销。

谢谢!

1 个答案:

答案 0 :(得分:0)

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读取时使用的转换。)< / p>

给出两个PCM源,可以使用加法器实时混合这两个源,将其转换为字节并通过单个SourceDataLine输出(请参见第1387 convertBufferToAudioBytes行方法)。如果在未播放的情况下从贡献者输入零,则SourceDataLine可以无限期运行。由于音频数据处理比系统消耗的速率要快得多,因此SDL将其大部分时间花费在阻塞状态,因此占用的CPU很少。