comparison util/matlab_midi/readmidi.m @ 81:a30e8bd6d948

matlab_midi scripts
author Ivan <ivan.damnjanovic@eecs.qmul.ac.uk>
date Mon, 28 Mar 2011 17:35:01 +0100
parents
children
comparison
equal deleted inserted replaced
80:16df822019f1 81:a30e8bd6d948
1 function midi = readmidi(filename, rawbytes)
2 % midi = readmidi(filename, rawbytes)
3 % midi = readmidi(filename)
4 %
5 % Read MIDI file and store in a Matlab structure
6 % (use midiInfo.m to see structure detail)
7 %
8 % Inputs:
9 % filename - input MIDI file
10 % rawbytes - 0 or 1: Include raw bytes in structure
11 % This info is redundant, but can be
12 % useful for debugging. default=0
13 %
14
15 % Copyright (c) 2009 Ken Schutte
16 % more info at: http://www.kenschutte.com/midi
17
18
19 if (nargin<2)
20 rawbytes=0;
21 end
22
23 fid = fopen(filename);
24 [A count] = fread(fid,'uint8');
25 fclose(fid);
26
27 if (rawbytes) midi.rawbytes_all = A; end
28
29 % realtime events: status: [F8, FF]. no data bytes
30 %clock, undefined, start, continue, stop, undefined, active
31 %sensing, systerm reset
32
33 % file consists of "header chunk" and "track chunks"
34 % 4B 'MThd' (header) or 'MTrk' (track)
35 % 4B 32-bit unsigned int = number of bytes in chunk, not
36 % counting these first 8
37
38
39 % HEADER CHUNK --------------------------------------------------------
40 % 4B 'Mthd'
41 % 4B length
42 % 2B file format
43 % 0=single track, 1=multitrack synchronous, 2=multitrack asynchronous
44 % Synchronous formats start all tracks at the same time, while asynchronous formats can start and end any track at any time during the score.
45 % 2B track cout (must be 1 for format 0)
46 % 2B num delta-time ticks per quarter note
47 %
48
49 if ~isequal(A(1:4)',[77 84 104 100]) % double('MThd')
50 error('File does not begin with header ID (MThd)');
51 end
52
53 header_len = decode_int(A(5:8));
54 if (header_len == 6)
55 else
56 error('Header length != 6 bytes.');
57 end
58
59 format = decode_int(A(9:10));
60 if (format==0 || format==1 || format==2)
61 midi.format = format;
62 else
63 error('Format does not equal 0,1,or 2');
64 end
65
66 num_tracks = decode_int(A(11:12));
67 if (format==0 && num_tracks~=1)
68 error('File is format 0, but num_tracks != 1');
69 end
70
71 time_unit = decode_int(A(13:14));
72 if (bitand(time_unit,2^15)==0)
73 midi.ticks_per_quarter_note = time_unit;
74 else
75 error('Header: SMPTE time format found - not currently supported');
76 end
77
78 if (rawbytes)
79 midi.rawbytes_header = A(1:14);
80 end
81
82 % end header parse ----------------------------------------------------
83
84
85
86
87
88
89 % BREAK INTO SEPARATE TRACKS ------------------------------------------
90 % midi.track(1).data = [byte byte byte ...];
91 % midi.track(2).date = ...
92 % ...
93 %
94 % Track Chunks---------
95 % 4B 'MTrk'
96 % 4B length (after first 8B)
97 %
98 ctr = 15;
99 for i=1:num_tracks
100
101 if ~isequal(A(ctr:ctr+3)',[77 84 114 107]) % double('MTrk')
102 error(['Track ' num2str(i) ' does not begin with track ID=MTrk']);
103 end
104 ctr = ctr+4;
105
106 track_len = decode_int(A(ctr:ctr+3));
107 ctr = ctr+4;
108
109 % have track.rawbytes hold initial 8B also...
110 track_rawbytes{i} = A((ctr-8):(ctr+track_len-1));
111
112 if (rawbytes)
113 midi.track(i).rawbytes_header = A(ctr-8:ctr-1);
114 end
115
116 ctr = ctr+track_len;
117 end
118 % ----------------------------------------------------------------------
119
120
121
122
123
124
125 % Events:
126 % - meta events: start with 'FF'
127 % - MIDI events: all others
128
129 % MIDI events:
130 % optional command byte + 0,1,or 2 bytes of parameters
131 % "running mode": command byte omitted.
132 %
133 % all midi command bytes have MSB=1
134 % all data for inside midi command have value <= 127 (ie MSB=0)
135 % -> so can determine running mode
136 %
137 % meta events' data may have any values (meta events have to set
138 % len)
139 %
140
141
142
143 % 'Fn' MIDI commands:
144 % no chan. control the entire system
145 %F8 Timing Clock
146 %FA start a sequence
147 %FB continue a sequence
148 %FC stop a sequence
149
150 % Meta events:
151 % 1B 0xFF
152 % 1B event type
153 % 1B length of additional data
154 % ?? additional data
155 %
156
157
158 % "channel mode messages"
159 % have same code as "control change": 0xBn
160 % but uses reserved controller numbers 120-127
161 %
162
163
164 %Midi events consist of an optional command byte
165 % followed by zero, one or two bytes of parameters.
166 % In running mode, the command can be omitted, in
167 % which case the last MIDI command specified is
168 % assumed. The first bit of a command byte is 1,
169 % while the first bit of a parameter is always 0.
170 % In addition, the last 4 bits of a command
171 % indicate the channel to which the event should
172 % be sent; therefore, there are 6 possible
173 % commands (really 7, but we will discuss the x'Fn'
174 % commands later) that can be specified. They are:
175
176
177 % parse tracks -----------------------------------------
178 for i=1:num_tracks
179
180 track = track_rawbytes{i};
181
182 if (rawbytes); midi.track(i).rawbytes = track; end
183
184 msgCtr = 1;
185 ctr=9; % first 8B were MTrk and length
186 while (ctr < length(track_rawbytes{i}))
187
188 clear currMsg;
189 currMsg.used_running_mode = 0;
190 % note:
191 % .used_running_mode is necessary only to
192 % be able to reconstruct a file _exactly_ from
193 % the 'midi' structure. this is helpful for
194 % debugging since write(read(filename)) can be
195 % tested for exact replication...
196 %
197
198 ctr_start_msg = ctr;
199
200 [deltatime,ctr] = decode_var_length(track, ctr);
201
202 % ?
203 %if (rawbytes)
204 % currMsg.rawbytes_deltatime = track(ctr_start_msg:ctr-1);
205 %end
206
207 % deltaime must be 1-4 bytes long.
208 % could check here...
209
210
211 % CHECK FOR META EVENTS ------------------------
212 % 'FF'
213 if track(ctr)==255
214
215 type = track(ctr+1);
216
217 ctr = ctr+2;
218
219 % get variable length 'length' field
220 [len,ctr] = decode_var_length(track, ctr);
221
222 % note: some meta events have pre-determined lengths...
223 % we could try verifiying they are correct here.
224
225 thedata = track(ctr:ctr+len-1);
226 chan = [];
227
228 ctr = ctr + len;
229
230 midimeta = 0;
231
232 else
233 midimeta = 1;
234 % MIDI EVENT ---------------------------
235
236
237
238
239 % check for running mode:
240 if (track(ctr)<128)
241
242 % make it re-do last command:
243 %ctr = ctr - 1;
244 %track(ctr) = last_byte;
245 currMsg.used_running_mode = 1;
246
247 B = last_byte;
248 nB = track(ctr); % ?
249
250 else
251
252 B = track(ctr);
253 nB = track(ctr+1);
254
255 ctr = ctr + 1;
256
257 end
258
259 % nibbles:
260 %B = track(ctr);
261 %nB = track(ctr+1);
262
263
264 Hn = bitshift(B,-4);
265 Ln = bitand(B,15);
266
267 chan = [];
268
269 msg_type = midi_msg_type(B,nB);
270
271 % DEBUG:
272 if (i==2)
273 if (msgCtr==1)
274 disp(msg_type);
275 end
276 end
277
278
279 switch msg_type
280
281 case 'channel_mode'
282
283 % UNSURE: if all channel mode messages have 2 data byes (?)
284 type = bitshift(Hn,4) + (nB-120+1);
285 thedata = track(ctr:ctr+1);
286 chan = Ln;
287
288 ctr = ctr + 2;
289
290 % ---- channel voice messages:
291 case 'channel_voice'
292
293 type = bitshift(Hn,4);
294 len = channel_voice_msg_len(type); % var length data:
295 thedata = track(ctr:ctr+len-1);
296 chan = Ln;
297
298 % DEBUG:
299 if (i==2)
300 if (msgCtr==1)
301 disp([999 Hn type])
302 end
303 end
304
305 ctr = ctr + len;
306
307 case 'sysex'
308
309 % UNSURE: do sysex events (F0-F7) have
310 % variable length 'length' field?
311
312 [len,ctr] = decode_var_length(track, ctr);
313
314 type = B;
315 thedata = track(ctr:ctr+len-1);
316 chan = [];
317
318 ctr = ctr + len;
319
320 case 'sys_realtime'
321
322 % UNSURE: I think these are all just one byte
323 type = B;
324 thedata = [];
325 chan = [];
326
327 end
328
329 last_byte = Ln + bitshift(Hn,4);
330
331 end % end midi event 'if'
332
333
334 currMsg.deltatime = deltatime;
335 currMsg.midimeta = midimeta;
336 currMsg.type = type;
337 currMsg.data = thedata;
338 currMsg.chan = chan;
339
340 if (rawbytes)
341 currMsg.rawbytes = track(ctr_start_msg:ctr-1);
342 end
343
344 midi.track(i).messages(msgCtr) = currMsg;
345 msgCtr = msgCtr + 1;
346
347
348 end % end loop over rawbytes
349 end % end loop over tracks
350
351
352 function val=decode_int(A)
353
354 val = 0;
355 for i=1:length(A)
356 val = val + bitshift(A(length(A)-i+1), 8*(i-1));
357 end
358
359
360 function len=channel_voice_msg_len(type)
361
362 if (type==128); len=2;
363 elseif (type==144); len=2;
364 elseif (type==160); len=2;
365 elseif (type==176); len=2;
366 elseif (type==192); len=1;
367 elseif (type==208); len=1;
368 elseif (type==224); len=2;
369 else
370 disp(type); error('bad channel voice message type');
371 end
372
373
374 %
375 % decode variable length field (often deltatime)
376 %
377 % return value and new position of pointer into 'bytes'
378 %
379 function [val,ptr] = decode_var_length(bytes, ptr)
380
381 keepgoing=1;
382 binarystring = '';
383 while (keepgoing)
384 % check MSB:
385 % if MSB=1, then delta-time continues into next byte...
386 if(~bitand(bytes(ptr),128))
387 keepgoing=0;
388 end
389 % keep appending last 7 bits from each byte in the deltatime:
390 binbyte = ['00000000' dec2base(bytes(ptr),2)];
391 binarystring = [binarystring binbyte(end-6:end)];
392 ptr=ptr+1;
393 end
394 val = base2dec(binarystring,2);
395
396
397
398
399 %
400 % Read first 2 bytes of msg and
401 % determine the type
402 % (most require only 1st byte)
403 %
404 % str is one of:
405 % 'channel_mode'
406 % 'channel_voice'
407 % 'sysex'
408 % 'sys_realtime'
409 %
410 function str=midi_msg_type(B,nB)
411
412 Hn = bitshift(B,-4);
413 Ln = bitand(B,7);
414
415 % ---- channel mode messages:
416 %if (Hn==11 && nB>=120 && nB<=127)
417 if (Hn==11 && nB>=122 && nB<=127)
418 str = 'channel_mode';
419
420 % ---- channel voice messages:
421 elseif (Hn>=8 && Hn<=14)
422 str = 'channel_voice';
423
424 % ---- sysex events:
425 elseif (Hn==15 && Ln>=0 && Ln<=7)
426 str = 'sysex';
427
428 % system real-time messages
429 elseif (Hn==15 && Ln>=8 && Ln<=15)
430 % UNSURE: how can you tell between 0xFF system real-time
431 % message and 0xFF meta event?
432 % (now, it will always be processed by meta)
433 str = 'sys_realtime';
434
435 else
436 % don't think it can get here...
437 error('bad midi message');
438 end