MIDI 或 WAV 文件为一系列频率和持续时间
是否有任何脚本/软件/算法允许将 MIDI(或 WAV)文件转换为 <频率、持续时间>
列表,以便我们可以重播该声音文件的“图像”,例如,通过C#中的System.Console.Beep(Frequency,duration)
函数?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您需要将 MIDI、WAV 或其他声音文件转换为原始音频样本。然后,对于连续的样本块(通常每个块重叠 50%),应用窗函数(例如 Hanning),然后进行 FFT,然后获取 FFT 输出箱的幅度,然后对于音频,您通常会取 20*log10这个幅度以获得 dB 值。
You need to convert the MIDI, WAV or other sound file to raw audio samples. Then for successive blocks of samples (typically overlapping each block by 50%), apply a window function (e.g. Hanning), then an FFT, then take the magnitude of the FFT output bins, then for audio you would usually take 20*log10 of this magnitude to get a dB value.
对于 MIDI,您必须自己解析文件(我已经这样做了,我推荐以下两个参考: 一个和两个),或者获取 MIDI 工具包。我不知道 .NET 有什么,但 这里是 Google搜索。
一旦你明白了,它应该相当容易。使用工具包读取 MIDI 文件,这将为您提供一组轨道。每个轨道包含一系列事件,每个事件都有一个相对于前一个事件的时间戳。一个事件可以是“注释打开”、“注释关闭”,也可以是您可能不关心并且可以在本练习中忽略的数百个其他事件之一。只需查找“note on”和“note off”事件即可。通常,每个音符都是一个“音符开”(具有一定的音高和力度,即音量),随后一段时间后是一个“音符关”(具有相同的音调,力度为 0)。
因此,有了这些信息,您可以构建一个具有四元组(开始时间、持续时间、音调、速度)的音符表,其中开始时间是“音符开启”事件的时间,持续时间是“音符开启”事件之间的时间差。 ”和“音符关闭”,音高/力度是“音符开启”的音高/力度。您可以使用此公式将音高转换为频率。
至于 WAV/MP3/AAC/OGG,所有这些都具有相同的技术,这就是 Paul 在他的回答中建议的。
For MIDI, you must either parse the file yourself (which I have done, and I recommend the following two references: one and two), or get a MIDI toolkit. I don't know of any for .NET but here is a Google search.
Once you get that, it should be fairly easy. Read in the MIDI file using the toolkit, and this will give you a set of tracks. Each track contains a sequence of events, each with a timestamp relative to the previous event. An event can be "note on", "note off", or one of hundreds of other events you probably don't care about and can ignore for this exercise. Just look for the "note on" and "note off" events. Usually, each note is a "note on" (with a certain pitch and velocity, which is volume) followed by a "note off" some time later (with the same pitch, and a velocity of 0).
So armed with this information, you can construct a table of notes with a quadruple (start time, duration, pitch, velocity), where start time is the time of the "note on" event, duration is the time difference between "note on" and "note off", and pitch/velocity is the pitch/velocity of the "note on". You can convert the pitch to frequency using this formula.
As for WAV/MP3/AAC/OGG, all of those have the same technique which is what Paul suggests in his answer.
Paul R 的解释对于 WAV 来说很好。
对于 MIDI,您必须选择一个轨道并读取 MIDI 数据。如何决定哪首曲目取决于您,但您实际上只能选择一个,因为使用您的方法一次只能从 PC 扬声器中听到一个“音符”。
C# MIDI 教程: http://www.codeproject.com/KB/audio-video /MIDIToolkit.aspx
一旦您阅读了该内容,您应该知道如何读取 MIDI 文件。从那里,您可以将其转换为频率和持续时间。持续时间取决于节奏和音符持续的刻度数,音调取决于音符编号及其相应的频率,根据 气质平等。 (如果你想变得真正疯狂,你甚至可以处理替代调音,但我现在不担心它。)
另外,我相信 NAudio 有一些用于读取文件的 MIDI 类,但它们可能并不完整。
当我们变得疯狂时...如果您可以有效地对其进行线程化(我想象这几乎是不可能的,但是...),对于 WAV 播放,您可以使用 PWM 驱动 PC 扬声器并模拟 PCM 音频播放。我记得一些旧的 Necrobones 的 DOS 游戏曾经这样做过,并且有一个适用于 Windows 3.1 的驱动程序在我的电脑上运行得很好33MHz 笔记本电脑可应对常见的咔哒声和叮当声。尽管来自托管框架(甚至在没有实时优先级的 Windows 中)的此方法可能非常困难。
Paul R's explanation is fine for WAV.
For MIDI, you're going to have to pick a track and read in the MIDI data. How you decide which track is up to you, but you can really only pick one, since you only get one "note" at a time out of the PC speaker, using your method.
C# MIDI Tutorial: http://www.codeproject.com/KB/audio-video/MIDIToolkit.aspx
Once you have read up on that, you should know how to read a MIDI file in. From there, you can translate that to frequencies and durations. The duration depends on tempo and the number of ticks that a note lasts, and the pitch will depend on a note number and its corresponding frequency according to equal temperament. (If you wanted to get really crazy, you could even handle alternate tunings, but I wouldn't worry about it for now.)
Also, I believe NAudio has some MIDI classes for reading files, but they may not be complete.
While we're getting crazy... if you could thread it effectively (this would be near impossible I'd imagine, but...), for WAV playback, you could use PWM to drive the PC speaker and emulate PCM audio playback. I remember some old DOS games from Necrobones used to do this, and there was a driver for Windows 3.1 that worked great on my 33MHz laptop for the usual clicks and dings. Although this method from a managed framework (or even within Windows without a realtime priority) might be very difficult.