Skip to content

Commit a92120d

Browse files
committed
support type 0 midi files, putting all notes on one track
1 parent b66dfa6 commit a92120d

File tree

5 files changed

+23
-7
lines changed

5 files changed

+23
-7
lines changed

MidiData.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ def __init__(self, midiFilename):
2121
self.isTicksPerBeat = True
2222
self.ticksPerBeat = headerData.ticksPerBeat
2323

24-
if headerData.formatType != 1:
24+
if headerData.formatType != 1 and headerData.formatType != 0:
2525
raise NotSupportedException("Midi files of format " + str(headerData.formatType)
2626
+ " are not supported")
2727

@@ -44,7 +44,7 @@ def __init__(self, midiFilename):
4444
# set up tempoChanges
4545
tempoChanges.reset()
4646
self.msPerBeat = 500 # default 120 bpm
47-
deltaTimeTotal = 0
47+
deltaTimeTotal = 0 # current time in ticks
4848
msTotal = 0 # current time in ms
4949
# add events
5050
while not(isinstance(event, EndOfTrackEvent)):
@@ -65,7 +65,8 @@ def __init__(self, midiFilename):
6565
msTotal = (event.deltaTime/self.ticksPerSecond)*.001
6666
# add event to trackData
6767
deltaTimeTotal = nextTotal
68-
event.setStartTime(msTotal)
68+
event.setStartTimeMs(msTotal)
69+
event.setStartTimeTicks(deltaTimeTotal)
6970
trackData.addEvent(event)
7071
self.tracks.append(trackData)
7172

MidiEvents.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ def __init__(self):
5858
self.deltaTime = None
5959
# start time in ms
6060
self.startTime = None
61+
# start time in ticks
62+
self.startTimeTicks = None
6163

6264
# set the delta time in clock ticks from the bytes representing delta time
6365
def setDeltaTimeFromBytes(self, deltaTimeBytes):
@@ -73,8 +75,11 @@ def __str__(self):
7375
" deltaTime: " + str(self.deltaTime))
7476

7577
# set start time in ms
76-
def setStartTime(self, startTime):
77-
self.startTime = startTime
78+
def setStartTimeMs(self, startTimeMs):
79+
self.startTime = startTimeMs
80+
81+
def setStartTimeTicks(self, startTimeTicks):
82+
self.startTimeTicks = startTimeTicks
7883

7984

8085
# ---------------------- Meta Events ------------------------------

Note.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,22 @@
11
class Note:
22
# start and end times are in ms
3-
def __init__(self, start, pitch, velocity, channel):
3+
def __init__(self, start, startTicks, pitch, velocity, channel):
44
self.pitch = pitch # note number
55
self.channel = channel
66
self.startTime = start
77
self.endTime = None
8+
self.startTimeTicks = startTicks
9+
self.endTimeTicks = None
810
self.velocity = velocity
911
self.releaseVelocity = None
1012
return
1113

1214
def setEndTime(self, endTime):
1315
self.endTime = endTime
1416

17+
def setEndTimeTicks(self, endTimeTicks):
18+
self.endTimeTicks = endTimeTicks
19+
1520
def setReleaseVelocity(self, releaseVelocity):
1621
self.releaseVelocity = releaseVelocity
1722

README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
Python-midi-analysis
22
====================
33
The idea here is to decode midi files into objects that are easy to extract data from, primary by making tracks into objects that contains notes, which are objects themselves.
4-
This will probably only work with type one midi files which are organized so that each track contains data for a separate instrument.
4+
This works with with type one midi and type zero midi files. For type zero midi files, a single track is creating containing all notes.
55

66
(This isn't meant to create or manipulate midi files; it is just to get data from them.)
77

@@ -31,8 +31,11 @@ TrackData: contains all the data for a single track
3131

3232
Note:
3333
* pitch: note number
34+
* channel: the midi channel
3435
* startTime: start time in ms
36+
* startTimeTicks: start time in ticks
3537
* endTime: end time in ms
38+
* endTimeTicks: end time in ticks
3639
* velocity: velocity
3740
* releaseVelocity: release velocity
3841
length(): length of the note in ms

TrackData.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,15 @@ def addEvent(self, event):
2929
+ " already playing, skipping...")
3030
else:
3131
self.incompleteNotes[event.noteNumber] = Note(event.startTime,
32+
event.startTimeTicks,
3233
event.noteNumber,
3334
event.velocity,
3435
event.channel)
3536
elif (isinstance(event, NoteOffEvent) or
3637
(isinstance(event, NoteOnEvent) and event.isNoteOff())):
3738
if event.noteNumber in self.incompleteNotes:
3839
self.incompleteNotes[event.noteNumber].setEndTime(event.startTime)
40+
self.incompleteNotes[event.noteNumber].setEndTimeTicks(event.startTimeTicks)
3941
self.notes.append(self.incompleteNotes[event.noteNumber])
4042
del self.incompleteNotes[event.noteNumber]
4143
elif self.debug:

0 commit comments

Comments
 (0)