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