Java中的Wav文件音乐转录

8
我有一个使用Java的音乐转录项目,问题是,我已经创建了一个小程序来记录声音并将其保存到WAV文件中,播放器应该只播放他/她想要转录的部分,然后我卡在了从保存的WAV文件中获取信息并使用此信息创建MIDI文件的点上,创建MIDI文件后,我必须为其生成音乐得分(乐谱),所有这些都必须在Java中完成。
我在各处搜索清晰的解释,但没有找到任何直接的 :( 由于我对Java很陌生,所以我希望有人能帮助我,请帮我解决以下编程难题:
1. 获取正在播放的WAV文件中有关音符的信息。 2. 知道音符。 3. 创建等效于WAV文件的MIDI文件。 4. 从MIDI文件生成得分。
我还尝试过对读取的数据进行分段后进行快速傅里叶变换,但我认为那完全走错了方向:(
如果有人可以帮助我解决上述问题,并告诉我如何仅使用Java编程,我将非常感激 :)
顺便说一下,该项目是: 播放器在钢琴上演奏音符>>记录他的演奏>>播放器获得他演奏的得分。

1
可能是将wav转换为midi的重复问题 - user7094
出于好奇,您是否不可以直接以MIDI格式读取输入?大多数乐器都支持某种形式的MIDI输出(如钢琴的MIDI键盘),似乎这将完全消除进行困难后处理的需要。 - templatetypedef
不通过已有的MIDI文件,为WAV文件生成分数的项目:D - Xtremeaiy
@Jam 这不是一个很好的编辑;如果你要花时间添加<br />换行符,那么你应该真正地将其变为一个“真实”的列表。此外,你可以在行末加两个空格来添加换行符,不需要使用<br /> - Yi Jiang
虽然这个问题与早期的问题相似,但是提问非常好。+1 - finnw
@Yi - 感谢您的反馈。下次我会记住的。 - Bojangles
5个回答

3

我在这个领域绝不是专家,如果这些都是胡说八道,我提前道歉。

要从文件中获取音符,我认为您需要对WAV文件进行FFT(快速傅里叶变换),但每次仅使用10毫秒的声音。然后,您会找到该时间段内FFT的最高峰,并继续移动到下一个“帧”(10毫秒或其他)。您再次执行FFT,如果最高峰的频率与上一个峰不同,则会说它是一个新音符。要查看音符的持续时间,请计算彼此之间阈值范围内的峰数,并将它们乘以每个帧的时间(10毫秒等)。

我再次声明,我不是专家,可能还有其他方法。

除此之外,我希望这可以帮助您...即使只是一点点。


嗯,它对我有点帮助,关于10毫秒分段的想法,谢谢 :) - Xtremeaiy
不客气!我很高兴那篇文章对你有点帮助 :-) - Bojangles

1

你想做的事情目前是不可能的。你所描述的范围已经超出了当前专业音乐程序所能做到的范畴,它们已经投入了数百年的程序员时间。

如果你大幅度削减需求,或许可以实现一些东西。

  • 要找到声音的音高,使用FFT;这是最容易的部分;在这里,你必须限制自己只针对单个音符,而无法清晰地读取和弦。

  • 你将无法发现曲子的拍号或速度(bpm)- 你唯一的机会就是在你的应用程序中包含某种形式的节拍器,并强制播放器遵守节奏。如果你想支持摇摆节奏,也必须由播放器进行配置。

  • 制作midi时,量化所有音符(将它们的开始和结束移动到最近的1/4、1/8或1/16小节)

  • 使用一个现成的排版系统来创建谱子;musictex可能适合你;生成一个tex文件比自己绘制要容易得多;如果我是你,我会忽略一些关于排版音乐的规则(我肯定会放弃连音符;它们有太多的规则)

如果你限制自己只演奏单一的旋律,忽略大部分的音乐排版,让钢琴演奏者使用你自己的节拍器并限制他的节奏选择,那么你可能会成功。


1

我在那个领域不是专家,但曾经尝试使用Xuggler(Java FFMPEG包装器)进行一些玩耍。这个库能够从媒体文件中提取许多有趣的数据,允许文件转码和许多其他酷炫的功能。这是链接:http://www.xuggle.com/xuggler/


1

我曾经也有同样的想法,并尝试了一个非常简单但不完整的解决方案。正如fdreger的帖子所指出的,即使是专业软件也无法正确执行此任务。(我尝试了一些IntelliScore、AudioScore和其他一些软件的演示版本,但这些软件在处理复调音乐时似乎都不是特别高效)

但是,如果你想自己尝试,我使用了在这里找到的源代码:http://www.psychicorigami.com/2009/01/17/a-5k-java-guitar-tuner/,它帮助我找到了如何确定频率。(FFT会更准确,但更加复杂)。

为了在屏幕上显示音符,我使用了abc4j库,可以在这里找到:http://code.google.com/p/abc4j/

但是,正如上面所指出的,它仅适用于单声部音乐(一个单独的声音)。

祝你好运!


0

有一个非常好用的开源音频编辑器叫做Audacity。是的,它使用C++编写,但您可能会在其源代码中找到您要寻找的答案。将C++代码翻译成Java并不那么困难。


非常感谢 :) 但我正在寻找Java中已经可用的东西来帮助我让这个东西工作,非常感谢,我将尝试从Audacity获取所需的所有信息 :D - Xtremeaiy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接