yjhuangcd
First commit
9965bf6
"""These classes simply hold MIDI data in a convenient form.
"""
from __future__ import print_function
from .utilities import key_number_to_key_name
class Note(object):
"""A note event.
Parameters
----------
velocity : int
Note velocity.
pitch : int
Note pitch, as a MIDI note number.
start : float
Note on time, absolute, in seconds.
end : float
Note off time, absolute, in seconds.
"""
def __init__(self, velocity, pitch, start, end):
if end < start:
raise ValueError("Note end time must be greater than start time")
self.velocity = velocity
self.pitch = pitch
self.start = start
self.end = end
def get_duration(self):
"""Get the duration of the note in seconds."""
return self.end - self.start
@property
def duration(self):
return self.get_duration()
def __repr__(self):
return 'Note(start={:f}, end={:f}, pitch={}, velocity={})'.format(
self.start, self.end, self.pitch, self.velocity)
class PitchBend(object):
"""A pitch bend event.
Parameters
----------
pitch : int
MIDI pitch bend amount, in the range ``[-8192, 8191]``.
time : float
Time where the pitch bend occurs.
"""
def __init__(self, pitch, time):
self.pitch = pitch
self.time = time
def __repr__(self):
return 'PitchBend(pitch={:d}, time={:f})'.format(self.pitch, self.time)
class ControlChange(object):
"""A control change event.
Parameters
----------
number : int
The control change number, in ``[0, 127]``.
value : int
The value of the control change, in ``[0, 127]``.
time : float
Time where the control change occurs.
"""
def __init__(self, number, value, time):
self.number = number
self.value = value
self.time = time
def __repr__(self):
return ('ControlChange(number={:d}, value={:d}, '
'time={:f})'.format(self.number, self.value, self.time))
class TimeSignature(object):
"""Container for a Time Signature event, which contains the time signature
numerator, denominator and the event time in seconds.
Attributes
----------
numerator : int
Numerator of time signature.
denominator : int
Denominator of time signature.
time : float
Time of event in seconds.
Examples
--------
Instantiate a TimeSignature object with 6/8 time signature at 3.14 seconds:
>>> ts = TimeSignature(6, 8, 3.14)
>>> print(ts)
6/8 at 3.14 seconds
"""
def __init__(self, numerator, denominator, time):
if not (isinstance(numerator, int) and numerator > 0):
raise ValueError(
'{} is not a valid `numerator` type or value'.format(
numerator))
if not (isinstance(denominator, int) and denominator > 0):
raise ValueError(
'{} is not a valid `denominator` type or value'.format(
denominator))
if not (isinstance(time, (int, float)) and time >= 0):
raise ValueError(
'{} is not a valid `time` type or value'.format(time))
self.numerator = numerator
self.denominator = denominator
self.time = time
def __repr__(self):
return "TimeSignature(numerator={}, denominator={}, time={})".format(
self.numerator, self.denominator, self.time)
def __str__(self):
return '{}/{} at {:.2f} seconds'.format(
self.numerator, self.denominator, self.time)
class KeySignature(object):
"""Contains the key signature and the event time in seconds.
Only supports major and minor keys.
Attributes
----------
key_number : int
Key number according to ``[0, 11]`` Major, ``[12, 23]`` minor.
For example, 0 is C Major, 12 is C minor.
time : float
Time of event in seconds.
Examples
--------
Instantiate a C# minor KeySignature object at 3.14 seconds:
>>> ks = KeySignature(13, 3.14)
>>> print(ks)
C# minor at 3.14 seconds
"""
def __init__(self, key_number, time):
if not all((isinstance(key_number, int),
key_number >= 0,
key_number < 24)):
raise ValueError(
'{} is not a valid `key_number` type or value'.format(
key_number))
if not (isinstance(time, (int, float)) and time >= 0):
raise ValueError(
'{} is not a valid `time` type or value'.format(time))
self.key_number = key_number
self.time = time
def __repr__(self):
return "KeySignature(key_number={}, time={})".format(
self.key_number, self.time)
def __str__(self):
return '{} at {:.2f} seconds'.format(
key_number_to_key_name(self.key_number), self.time)
class Lyric(object):
"""Timestamped lyric text.
Attributes
----------
text : str
The text of the lyric.
time : float
The time in seconds of the lyric.
"""
def __init__(self, text, time):
self.text = text
self.time = time
def __repr__(self):
return 'Lyric(text="{}", time={})'.format(
self.text.replace('"', r'\"'), self.time)
def __str__(self):
return '"{}" at {:.2f} seconds'.format(self.text, self.time)
class Text(object):
"""Timestamped text event.
Attributes
----------
text : str
The text.
time : float
The time it occurs in seconds.
"""
def __init__(self, text, time):
self.text = text
self.time = time
def __repr__(self):
return 'Text(text="{}", time={})'.format(
self.text.replace('"', r'\"'), self.time)
def __str__(self):
return '"{}" at {:.2f} seconds'.format(self.text, self.time)