annotate util/matlab_midi/matrix2midi.m @ 143:8d866d96f006

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