一个简单的MIDI文件解析器

MIDIFile的Python项目详细描述


一个简单的python3midi文件/流解析器/解码器

简介

美国石油学会

顶级名称空间是MIDI,它包含两个类:MIDI.MIDIFile文件迷笛音轨。在

MIDI.MIDIFile文件

表示由MIDI Association定义的标准Midi格式(SMF)数据文件。MIDI.MIDIFile文件对象是可编辑的,类似数组。在

构造函数

MIDI.MIDIFile文件初始化(selffilename

^{tt1}$the name of an SMF file to read and parse. Raises an exception if the file does not exist / cannot be read.

方法
MIDI.MIDIFile.parse(self)Parse the file. Determines the file’s type and populates an array of content tracks, each of which contains one track from the file and is represented by a MIDI.Track instance.
MIDI.MIDIFile.__len__(self)The number of tracks in the file (0 if ^{tt3}$ has not yet been invoked).
MIDI.MIDIFile.__iter__(self)Iterates over the tracks in the file
MIDI.MIDIFile.__get_item__(self, ^{tt4}$)A MIDI.Track object, representing the ^{tt4}$’th track in the file (or throws a RangeError if ^{tt4}$ is out of range)
MIDI.MIDIFile.__str__(self)Useful information about the file as a whole, number of tracks and their sizes

属性

如果selfMIDI.MIDI文件实例

self.formatintThe MIDI format of the loaded file. Possible values are 0, 1 and 2 (or None if the ^{tt3}$ method has not yet been invoked). See page 134 of the MIDI Specification v1.0.
self.divisionuint16

Time quantum of the MIDI data encoded in the file (or ^{tt8}$ if the ^{tt3}$ method has not yet been invoked). Interpretation depends on the value:

  • < 32768 : equals number of ticks per quarter-note; often equal to ^{tt10}$
  • >=32786 : number of subdivisions of a second as defined in the SMTPE Standard and on pages 116- of the MIDI Specification v1.0. Equals 32768 + 256 f + t where f identifies one of the standard MIDI time code formats, and signifies the number of frames per second, while f is the numbef of subdivisions within a frame (common values are 4, 8, 10, 80 and 100).

迷笛音轨

类表示来自SMF文件或MIDI事件集合的单轨。迷笛音轨对象是可编辑的,类似数组。在

构造函数

迷笛音轨初始化(selfdatacontainsTiming = True

参数:

^{tt11}$binary string or arraydata comprising one track from an SMF file, or a sequence of MIDI messages
^{tt14}$booleanTrue if ^{tt11}$ consists of MIDI events interleaved with timestamps (as in an SMF file); False if it is a sequence of MIDI messages

所以,举个例子

track=Track(data,containsTiming=True)

initialises ^{tt16}$ for parsing ^{tt11}$ representing a track taken from an SMF file; while

track=Track(data,containsTiming=False)

initialises ^{tt16}$ for parsing ^{tt11}$ consisting of a sequence of one or more raw MIDI events, e.g. captured from an observed MIDI stream, or sent to the application by a MIDI controller.

方法
MIDI.Track.parse(self)Parse the track into an array of events, ordered based on their appearance in the track. Events are represented by instances of MIDI.Events.Event.
MIDI.Track.__len__(self)Returns the number of messages in the track (0 if ^{tt3}$ has not yet been invoked).
MIDI.Track.__iter__(self)Iterates over the events / messages in the track, in the order in which they appeared.
MIDI.Track.__get_item__(self, ^{tt4}$)Returns a MIDI.Events.Event instance representing the ^{tt4}$’th event in the track (or throws a RangeError if ^{tt4}$ is out of range).
MIDI.Track.__str__(self)Returns string representations of all the track’s events, concatenated and separated by newline ^{tt24}$.

MIDI.Events.事件

表示在SMF文件或MIDI消息流中找到的常规事件。特定类型的事件由子类表示(见下文)。在

构造函数

MIDI.Events.Event.__init__(self, ^{tt25}$, ^{tt26}$)

Arguments:

^{tt25}$uint64MIDI timestamp for the time of the event’s occurrence, relative to some arbitrary zero.
^{tt26}$binary string or arraybytes making up the event.

方法
MIDI.Events.Event.__len__(self)The total length of the event.
MIDI.Events.Event.__str__(self)String representation of the event. By default, a representation of the raw bytes as a binary string.

属性

如果selfMIDI.Events.事件实例

self.timethe timestamp with which the event instance was initialised; measured in units of the quantum of time defined by the value of the ^{tt29}$ property of the MIDI.MIDIFile instance containing the track of which this event forms a part.
self.headerthe event’s initial byte, which serves to identify its kind.
self.databinary string or array containing the event’s body, i.e. its data content, with the header byte and other formatting removed

此类的专门化描述了特定类型的SMF事件,提供了各种动态生成的只读属性,描述了特定于它们的属性。具体如下:

Meta Events

提供有关曲目的信息,例如歌词、节奏等,用类型^{str1}表示$MIDI.Events.MetaEvent,它具有以下附加属性:

^{tt30}$is the meta event’s kind, expressed as a member of the enumeration MIDI.Events.meta.MetaEventKinds for defined message types (see pages 137-139 of the MIDI Specification v1.0 for a complete list) , and None otherwise

其他参数仅适用于以下特定事件类型:

PropertyDescriptionMeta Event Type(s)
^{tt31}$general textText, Copyright_Notice, Track_Name, Instrument_Name, Lyric, Marker, Cue_Point
^{tt32}$sequence numberSequence_Number
^{tt33}$channel numberMIDI_Channel_Prefix
^{tt34}$tempoSet_Tempo
^{tt35}$hoursSMTPE_Offset
^{tt36}$minutesSMTPE_Offset
^{tt37}$secondsSMTPE_Offset
^{tt38}$framesSMTPE_Offset
^{tt39}$time signature top numberTime_Signature
^{tt40}$time signature bottom numberTime_Signature
^{tt41}$number of MIDI clocks per tickTime_Signature
^{tt42}$what it saysTime_Signature

系统事件

告诉MIDI乐器如何执行音轨,并用^{str 1}类型表示$MIDI.Events.SysExEvent。每个系统事件都包含一条MIDI System消息。如果self是^{str 1}的实例$MIDI.Events.SysExEvent然后:

^{tt44}$uint8is the MIDI system message’s kind, expressed as an integer 0 - 15; it is equal to ^{tt45}$

MIDI事件

告诉MIDI乐器在执行曲目时要播放什么,并用类型^{str 1}表示$MIDI.Events.MIDIEvent。所有实例都有以下字段:

^{tt46}$uint8The message command type, as defined in the MIDI Specification v1.0. Equal to ^{tt47}$
^{tt33}$uint8The channel that the message relates to. Equal to ^{tt45}$
^{tt30}$message type specificInstance of a class representing this particular kind of MIDI message; depending on ^{tt46}$

根据消息类型,ev.message的值如下:

NOTE-OFF or NOTE-ON (^{tt53}$)

^{tt54}$ON if this is a NOTE-ON message; OFF if it is a NOTE-OFF message
^{tt55}$The note to which the message refers
^{tt56}$The velocity with which the note is applied

按键压力command = 0xa0

^{tt55}$The note to which the message refers
^{tt59}$The pressure with which the note is applied

控件更改command = 0xb0

^{tt46}$The control that should be changed; represented either as a named object, for known controls, or as an unsigned integer for others
^{tt59}$The new value of the control; converted to ON / OFF, etc for known controls, left as an unsigned integer for others

程序更改command = 0xc0

^{tt64}$always equal to “Program”
^{tt65}$The new program number

通道压力command = 0xd0

^{tt64}$always equal to “Pressure”
^{tt65}$The new pressure value for the channel as an unsigned integer

PITCH BEND CHANGEcommand = 0xe0

^{tt64}$always equal to “BEND”
^{tt65}$The new pitch bend for the channel as a signed integer b such that -2048 <= b <= 2047

示例

包中包含以下简单的测试脚本:

fromMIDIimportMIDIFilefromsysimportargvdefparse(file):c=MIDIFile(file)c.parse()print(str(c))foridx,trackinenumerate(c):track.parse()print(f'Track {idx}:')print(str(track))parse(argv[1])

将此应用于SMF文件的输出的前几行如下:

Format 1 nTracks 4 division 960
       Track 0 of length 0
       Track 1 of length 0
       Track 2 of length 0
       Track 3 of length 0
Track 0:
META@0 Key Signature -> key=C mode=major
META@0 Set Tempo -> tempo=128.57136
META@0 Track Name -> text=b'It was a punter and a pro'
META@0 Text -> text=b'Julian Porter'
META@0 Copyright Notice -> text=b'Copyright \xa9 Julian Porter'
META@1 End Of Track ->
Track 1:
MIDI@6336 0[0]
MIDI@6336 CONTROL_CHANGE[1] Pan := 16
MIDI@6336 CONTROL_CHANGE[1] Channel Volume := 112
META@6336 Track Name -> text=b'Soprano'
META@10656 Lyric -> text=b'It '
MIDI@10656 NOTE_ON[1] E5 ON velocity := 36
MIDI@11136 NOTE_OFF[1] E5 OFF velocity := 0
META@11136 Lyric -> text=b'was '
MIDI@11136 NOTE_ON[1] G#5 ON velocity := 36
MIDI@11616 NOTE_OFF[1] G#5 OFF velocity := 0
META@11616 Lyric -> text=b'a '
MIDI@11616 NOTE_ON[1] C6 ON velocity := 36
MIDI@12096 NOTE_OFF[1] C6 OFF velocity := 0
META@12096 Lyric -> text=b'pun'
MIDI@12096 NOTE_ON[1] A#5 ON velocity := 36
MIDI@12576 NOTE_OFF[1] A#5 OFF velocity := 0
META@12576 Lyric -> text=b'ter '
MIDI@12576 CONTROL_CHANGE[1] RPN MSB := 0
MIDI@12576 CONTROL_CHANGE[1] RPN LSB := 0
MIDI@12576 CONTROL_CHANGE[1] Data Entry MSB := 4
MIDI@12576 CONTROL_CHANGE[1] Data Entry LSB := 0
MIDI@12576 PITCH_BEND[1] Bend := -8192
MIDI@12576 PITCH_BEND[1] Bend := 8191
MIDI@12591 PITCH_BEND[1] Bend := 7927
MIDI@12606 PITCH_BEND[1] Bend := 7663
MIDI@12621 PITCH_BEND[1] Bend := 7399
MIDI@12636 PITCH_BEND[1] Bend := 7134
MIDI@12651 PITCH_BEND[1] Bend := 6870
MIDI@12651 NOTE_ON[1] C#6 ON velocity := 36
MIDI@12666 PITCH_BEND[1] Bend := 6606
MIDI@12681 PITCH_BEND[1] Bend := 6342
MIDI@12696 PITCH_BEND[1] Bend := 6077
MIDI@12711 PITCH_BEND[1] Bend := 5813

这清楚地显示了文件的整体结构(有四个音轨)、初始元数据音轨的内容(指定了节奏、键等)和第二个音轨的开始(混合了指定乐器应该演奏什么的MIDI消息)和提供歌词的元数据等

要求

MIDIFile是一个纯python模块,需要运行python3.6或更高版本(这可以通过使用python3.6的f'...{x}'string interpo的更冗长的等价物来减少关系语法)。在

众所周知,它可以在MacOS和Linux上运行。它应该在Windows上运行,但是当涉及Windows时,没有什么是确定的,是吗?尝试让它在Windows上运行是你自己的风险。在

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
java将变量从一个类发送到另一个类   使用Java Kubernetes客户端Api部署pod   sql如何从oracle检索图像并在java框架中显示   java更改Clover检测类的位置   java安卓位置。getAccuracy()返回1   运行时。不支持Java ME 8上的exec()。还有别的选择吗?   bdd在Java中运行Cucumber时修改CucumberOptions标记   在java中将方法更改为运行时异常   构造函数类中的Java NullPointerException   java SetResizeable(false)不会阻止双击后的帧还原   java智能卡终端移除:SCARD_E_无服务卡例外   Java正则表达式和组   爪哇骑士巡回赛   端口8443上通过ssl的java Spring安全登录在使用http协议的端口8080上无法识别   java如何确定读取文件的哪一行特定行