Mercurial > hg > smallbox
comparison util/matlab_midi/matrix2midi.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=matrix2midi(M,ticks_per_quarter_note,timesig) | |
2 % midi=matrix2midi(M,ticks_per_quarter_note) | |
3 % | |
4 % generates a midi matlab structure from a matrix | |
5 % specifying a list of notes. The structure output | |
6 % can then be used by writemidi.m | |
7 % | |
8 % M: input matrix: | |
9 % 1 2 3 4 5 6 | |
10 % [track chan nn vel t1 t2] (any more cols ignored...) | |
11 % | |
12 % optional arguments: | |
13 % - ticks_per_quarter_note: integer (default 300) | |
14 % - timesig: a vector of len 4 (default [4,2,24,8]) | |
15 % | |
16 | |
17 % Copyright (c) 2009 Ken Schutte | |
18 % more info at: http://www.kenschutte.com/midi | |
19 | |
20 % TODO options: | |
21 % - note-off vs vel=0 | |
22 % - tempo, ticks, etc | |
23 | |
24 if nargin < 2 | |
25 ticks_per_quarter_note = 300; | |
26 end | |
27 | |
28 if nargin < 3 | |
29 timesig = [4,2,24,8]; | |
30 end | |
31 | |
32 tracks = unique(M(:,1)); | |
33 Ntracks = length(tracks); | |
34 | |
35 % start building 'midi' struct | |
36 | |
37 if (Ntracks==1) | |
38 midi.format = 0; | |
39 else | |
40 midi.format = 1; | |
41 end | |
42 | |
43 midi.ticks_per_quarter_note = ticks_per_quarter_note; | |
44 | |
45 tempo = 500000; % could be set by user, etc... | |
46 % (microsec per quarter note) | |
47 | |
48 for i=1:Ntracks | |
49 | |
50 trM = M(i==M(:,1),:); | |
51 | |
52 note_events_onoff = []; | |
53 note_events_n = []; | |
54 note_events_ticktime = []; | |
55 | |
56 % gather all the notes: | |
57 for j=1:size(trM,1) | |
58 % note on event: | |
59 note_events_onoff(end+1) = 1; | |
60 note_events_n(end+1) = j; | |
61 note_events_ticktime(end+1) = 1e6 * trM(j,5) * ticks_per_quarter_note / tempo; | |
62 | |
63 % note off event: | |
64 note_events_onoff(end+1) = 0; | |
65 note_events_n(end+1) = j; | |
66 note_events_ticktime(end+1) = 1e6 * trM(j,6) * ticks_per_quarter_note / tempo; | |
67 end | |
68 | |
69 | |
70 msgCtr = 1; | |
71 | |
72 % set tempo... | |
73 midi.track(i).messages(msgCtr).deltatime = 0; | |
74 midi.track(i).messages(msgCtr).type = 81; | |
75 midi.track(i).messages(msgCtr).midimeta = 0; | |
76 midi.track(i).messages(msgCtr).data = encode_int(tempo,3); | |
77 midi.track(i).messages(msgCtr).chan = []; | |
78 msgCtr = msgCtr + 1; | |
79 | |
80 % set time sig... | |
81 midi.track(i).messages(msgCtr).deltatime = 0; | |
82 midi.track(i).messages(msgCtr).type = 88; | |
83 midi.track(i).messages(msgCtr).midimeta = 0; | |
84 midi.track(i).messages(msgCtr).data = timesig(:); | |
85 midi.track(i).messages(msgCtr).chan = []; | |
86 msgCtr = msgCtr + 1; | |
87 | |
88 [junk,ord] = sort(note_events_ticktime); | |
89 | |
90 prevtick = 0; | |
91 for j=1:length(ord) | |
92 | |
93 n = note_events_n(ord(j)); | |
94 cumticks = note_events_ticktime(ord(j)); | |
95 | |
96 midi.track(i).messages(msgCtr).deltatime = cumticks - prevtick; | |
97 midi.track(i).messages(msgCtr).midimeta = 1; | |
98 midi.track(i).messages(msgCtr).chan = trM(n,2); | |
99 midi.track(i).messages(msgCtr).used_running_mode = 0; | |
100 | |
101 if (note_events_onoff(ord(j))==1) | |
102 % note on: | |
103 midi.track(i).messages(msgCtr).type = 144; | |
104 midi.track(i).messages(msgCtr).data = [trM(n,3); trM(n,4)]; | |
105 else | |
106 %-- note off msg: | |
107 %midi.track(i).messages(msgCtr).type = 128; | |
108 %midi.track(i).messages(msgCtr).data = [trM(n,3); trM(n,4)]; | |
109 %-- note on vel=0: | |
110 midi.track(i).messages(msgCtr).type = 144; | |
111 midi.track(i).messages(msgCtr).data = [trM(n,3); 0]; | |
112 end | |
113 msgCtr = msgCtr + 1; | |
114 | |
115 prevtick = cumticks; | |
116 end | |
117 | |
118 % end of track: | |
119 midi.track(i).messages(msgCtr).deltatime = 0; | |
120 midi.track(i).messages(msgCtr).type = 47; | |
121 midi.track(i).messages(msgCtr).midimeta = 0; | |
122 midi.track(i).messages(msgCtr).data = []; | |
123 midi.track(i).messages(msgCtr).chan = []; | |
124 msgCtr = msgCtr + 1; | |
125 | |
126 end | |
127 | |
128 | |
129 % return a _column_ vector | |
130 % (copied from writemidi.m) | |
131 function A=encode_int(val,Nbytes) | |
132 | |
133 A = zeros(Nbytes,1); %ensure col vector (diff from writemidi.m...) | |
134 for i=1:Nbytes | |
135 A(i) = bitand(bitshift(val, -8*(Nbytes-i)), 255); | |
136 end | |
137 |