comparison util/matlab_midi/writemidi.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 rawbytes=writemidi(midi,filename,do_run_mode)
2 % rawbytes=writemidi(midi,filename,do_run_mode)
3 %
4 % writes to a midi file
5 %
6 % midi is a structure like that created by readmidi.m
7 %
8 % do_run_mode: flag - use running mode when possible.
9 % if given, will override the msg.used_running_mode
10 % default==0. (1 may not work...)
11 %
12 % TODO: use note-on for note-off... (for other function...)
13 %
14
15 % Copyright (c) 2009 Ken Schutte
16 % more info at: http://www.kenschutte.com/midi
17
18
19 %if (nargin<3)
20 do_run_mode = 0;
21 %end
22
23
24 % do each track:
25 Ntracks = length(midi.track);
26
27 for i=1:Ntracks
28
29 databytes_track{i} = [];
30
31 for j=1:length(midi.track(i).messages)
32
33 msg = midi.track(i).messages(j);
34
35 msg_bytes = encode_var_length(msg.deltatime);
36
37 if (msg.midimeta==1)
38
39 % check for doing running mode
40 run_mode = 0;
41 run_mode = msg.used_running_mode;
42
43 % should check that prev msg has same type to allow run
44 % mode...
45
46
47 % if (j>1 && do_run_mode && msg.type == midi.track(i).messages(j-1).type)
48 % run_mode = 1;
49 % end
50
51
52 msg_bytes = [msg_bytes; encode_midi_msg(msg, run_mode)];
53
54
55 else
56
57 msg_bytes = [msg_bytes; encode_meta_msg(msg)];
58
59 end
60
61 % disp(msg_bytes')
62
63 %if (msg_bytes ~= msg.rawbytes)
64 % error('rawbytes mismatch');
65 %end
66
67 databytes_track{i} = [databytes_track{i}; msg_bytes];
68
69 end
70 end
71
72
73 % HEADER
74 % double('MThd') = [77 84 104 100]
75 rawbytes = [77 84 104 100 ...
76 0 0 0 6 ...
77 encode_int(midi.format,2) ...
78 encode_int(Ntracks,2) ...
79 encode_int(midi.ticks_per_quarter_note,2) ...
80 ]';
81
82 % TRACK_CHUCKS
83 for i=1:Ntracks
84 a = length(databytes_track{i});
85 % double('MTrk') = [77 84 114 107]
86 tmp = [77 84 114 107 ...
87 encode_int(length(databytes_track{i}),4) ...
88 databytes_track{i}']';
89 rawbytes(end+1:end+length(tmp)) = tmp;
90 end
91
92
93 % write to file
94 fid = fopen(filename,'w');
95 %fwrite(fid,rawbytes,'char');
96 fwrite(fid,rawbytes,'uint8');
97 fclose(fid);
98
99 % return a _column_ vector
100 function A=encode_int(val,Nbytes)
101
102 for i=1:Nbytes
103 A(i) = bitand(bitshift(val, -8*(Nbytes-i)), 255);
104 end
105
106
107 function bytes=encode_var_length(val)
108
109 binStr = dec2base(round(val),2);
110 Nbytes = ceil(length(binStr)/7);
111
112 binStr = ['00000000' binStr];
113 bytes = [];
114 for i=1:Nbytes
115 if (i==1)
116 lastbit = '0';
117 else
118 lastbit = '1';
119 end
120 B = bin2dec([lastbit binStr(end-i*7+1:end-(i-1)*7)]);
121 bytes = [B; bytes];
122 end
123
124
125 function bytes=encode_midi_msg(msg, run_mode)
126
127 bytes = [];
128
129 if (run_mode ~= 1)
130 bytes = msg.type;
131 % channel:
132 bytes = bytes + msg.chan; % lower nibble should be chan
133 end
134
135 bytes = [bytes; msg.data];
136
137 function bytes=encode_meta_msg(msg)
138
139 bytes = 255;
140 bytes = [bytes; msg.type];
141 bytes = [bytes; encode_var_length(length(msg.data))];
142 bytes = [bytes; msg.data];
143