MIDI 或 WAV 文件到频率和持续时间的数组

Posted

技术标签:

【中文标题】MIDI 或 WAV 文件到频率和持续时间的数组【英文标题】:MIDI or WAV file to an array of frequencies and duration 【发布时间】:2011-03-20 07:22:41 【问题描述】:

是否有任何脚本/软件/算法允许将 MIDI(或 WAV)文件转换为 <frequency, duration> 列表,以便我们可以重放此声音文件的“图像”,例如,通过 @987654322 C#中的@函数?

【问题讨论】:

你在那里问了两个完全不同的问题。 MIDI 和 WAV 完全不同,不仅在格式上,而且在它们存储音频方式的整个概念上。 MIDI 将音频存储为一系列音符,因此提取频率和持续时间对是微不足道的(我不知道有什么特定的软件可以做到这一点;我已经编写了自己的软件来以一种非常 hacky 的方式做到这一点) . WAV 是数字样本,因此您需要频率分析软件来获取音符数据。这是可能的,但不是 100% 准确和完全不同的鱼锅。那你想要哪个? 至少,如何处理 MIDI 文件(但也告诉我 WAV 的原理,因为我很好奇,我在某处读到 FFT 不足) 这真是一个迷人的想法。可能您将 WAV 文件转换为频域(例如 FFT),然后应用心理声学模型来挑选人类会听到的单个“哔”声。类似于 Photoshop“印象派”滤镜的音频等价物... 把这当作两个完全不同的问题来问,你可能会得到更好的答案。 【参考方案1】:

您需要将 MIDI、WAV 或其他声音文件转换为原始音频样本。然后对于连续的样本块(通常将每个块重叠 50%),应用窗口函数(例如 Hanning),然后是 FFT,然后取 FFT 输出箱的幅度,然后对于音频,您通常需要 20*log10这个幅度来获得一个dB值。

【讨论】:

+1,这对 WAV 很好,但不要为 MIDI 使用这种方法。如果你有 MIDI 的东西,那么不要合成它并读回来。 @Brad:这取决于您是只想要音符信息(当然您可以直接从 MIDI 数据中获取)还是想要完整的音频频谱 - OP 的问题对于什么非常模糊他想要的那种“形象”。 请注意,这种 FFT 方法将给出声音中的近似频谱频率,而不是音乐中的音符或音高频率。持续时间也将被量化为 FFT 窗口的时间步长,这可能是也可能不是任何实际音符或音调爆发长度的准确度量。【参考方案2】:

对于 MIDI,您必须自己解析文件(我已经这样做了,我推荐以下两个参考:one 和 two),或者获取 MIDI 工具包。我不知道任何.NET 但here is a Google search。

一旦你得到它,它应该是相当容易的。使用工具包读入 MIDI 文件,这将为您提供一组 音轨。每个轨道都包含一系列事件,每个事件都有一个相对于前一个事件的时间戳。一个事件可以是“note on”、“note off”,或者是数百个您可能不关心并且可以在本练习中忽略的其他事件之一。只需查找“note on”和“note off”事件。通常,每个音符都是一个“音符开”(具有一定的音高和力度,即音量),然后是一段时间后的“音符关”(具有相同的音高,力度为 0)。

因此,有了这些信息,您可以构建一个带有四元组(开始时间、持续时间、音高、速度)的音符表,其中开始时间是“音符打开”事件的时间,持续时间是两个音符之间的时间差“note on”和“note off”,音高/速度是“note on”的音高/速度。您可以使用this formula 将音高转换为频率。

至于 WAV/MP3/AAC/OGG,所有这些都具有相同的技术,这是 Paul 在他的回答中建议的。

【讨论】:

【参考方案3】:

Paul R 的解释适用于 WAV。

对于 MIDI,您将不得不选择一个音轨并读取 MIDI 数据。您如何决定哪一首曲目取决于您,但您实际上只能选择一首,因为使用您的方法一次只能从 PC 扬声器中获得一个“音符”。

C# MIDI 教程:http://www.codeproject.com/KB/audio-video/MIDIToolkit.aspx

读完之后,您应该知道如何读入 MIDI 文件。从那里,您可以将其转换为频率和持续时间。持续时间取决于速度和音符持续的节拍数,音高取决于音符编号及其对应的频率,根据equal temperament。 (如果你想真正疯狂,你甚至可以处理交替调音,但我暂时不用担心。)

另外,我相信NAudio has some MIDI classes for reading files,但它们可能并不完整。

虽然我们越来越疯狂...如果您可以有效地穿线(我想这几乎是不可能的,但是...),对于 WAV 播放,您可以使用PWM to drive the PC speaker and emulate PCM audio playback。我记得一些旧的DOS games from Necrobones 曾经这样做过,并且有一个适用于 Windows 3.1 的驱动程序在我的 33MHz 笔记本电脑上运行良好,可以正常点击和叮当。尽管这种来自托管框架(甚至在没有实时优先级的 Windows 中)的方法可能非常困难。

【讨论】:

以上是关于MIDI 或 WAV 文件到频率和持续时间的数组的主要内容,如果未能解决你的问题,请参考以下文章

wav到midi转换

音频数据文件格式(PCM,WAV,MIDI)简记

使用python从频率数组中进行音调扫描

如何使用 java 从 pcm 字节数组 .wav 文件中获取频率和音高?

如何从 wav 文件中获取时域频率?

有没有人在 iPhone 上通过 midi->wav 转换等播放 .midi 文件的经验?