Mercurial > hg > smallbox
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 |