在Haskell中创建MIDI文件

时间:2014-10-02 07:06:49

标签: haskell midi

我想创建一个生成MIDI文件的简单程序。不,我不想使用Haskore,因为这个项目有点过分。我觉得像this library这样的东西就足够了。

我希望能够做到:

  • 创建新的MIDI文件;
  • 将一些事件写入其中(我想及时控制速度,音高和位置);
  • 保存MIDI文件。

就这么简单,我打赌这并不难,但我找不到任何好的例子。

请提供一个基本示例或指出我在哪里可以找到有关在Haskell中创建MIDI文件的信息。

注意:我没有问你关于好库的问题,我问你如何在Haskell中做到这一点(你认为任何你认为适合使用的库)。

1 个答案:

答案 0 :(得分:6)

前言

好的,我不确定这是一个好问题,但我不能再等了,所以这里是如何使用Haskell编写一些MIDI。我应该注意到这个主题几乎没有记录,除了一些看起来相当神秘的包描述。

最适合我们需求的简约套餐是HCodecs,似乎会定期更新。我们对模块Codec.Midi感兴趣。

MIDI事件

在此库中,事件应表示为元组:

(time-offset, message)

其中time-offset是最后一个事件与新事件之间的时间间隔(参见下面如何设置每个节拍的刻度数)。 message必须是Message类型,可以找到完整的构造函数列表here。这些构造函数对应于所有基本的MIDI事件。

创建曲目

Track是一个事件列表。所以我们现在可以写一些非常简单的东西了:

track0 = [(0,  NoteOn 0 60 80),
          (24, NoteOff 0 60 0),
          (0,  TrackEnd)]

这是一个音符(60 =中间C),我们在这里使用了事件NoteOnNoteOff(它与NoteOn速度的0相同,所以在实践中,人们往往只使用NoteOn)。有关Google可以在这里做什么的更多信息,关于MIDI格式!

让我们创建一个包含E:

的曲目
track1 = [(0,  NoteOn 0 64 80),
          (24, NoteOn 0 64 0),
          (0,  TrackEnd)]

大!是时候将数据放入MIDI容器了。

走到一起!

让我们创建代表整个MIDI文件的对象。我们将使用Midi datatype的构造函数。

myMidi = Midi { fileType = MultiTrack, 
                timeDiv  = TicksPerBeat 24, 
                tracks   = [track0, track1] }

就是这样! timeDiv定义了音轨的量化,如果我们每个节拍有24个音符,我们的音符将完全适合一个节拍(当然,你可以添加一些事件来设置速度和内容,试试吧!)。

保存资料

要保存Midi,我们应该使用exportFile(点击链接了解更多信息......好的,开个玩笑甚至没有单行描述):

exportFile "my-midi.mid" myMidi

完成。