ivan@81: function midi=matrix2midi(M,ticks_per_quarter_note,timesig) ivan@81: % midi=matrix2midi(M,ticks_per_quarter_note) ivan@81: % ivan@81: % generates a midi matlab structure from a matrix ivan@81: % specifying a list of notes. The structure output ivan@81: % can then be used by writemidi.m ivan@81: % ivan@81: % M: input matrix: ivan@81: % 1 2 3 4 5 6 ivan@81: % [track chan nn vel t1 t2] (any more cols ignored...) ivan@81: % ivan@81: % optional arguments: ivan@81: % - ticks_per_quarter_note: integer (default 300) ivan@81: % - timesig: a vector of len 4 (default [4,2,24,8]) ivan@81: % ivan@81: ivan@81: % Copyright (c) 2009 Ken Schutte ivan@81: % more info at: http://www.kenschutte.com/midi ivan@81: ivan@81: % TODO options: ivan@81: % - note-off vs vel=0 ivan@81: % - tempo, ticks, etc ivan@81: ivan@81: if nargin < 2 ivan@81: ticks_per_quarter_note = 300; ivan@81: end ivan@81: ivan@81: if nargin < 3 ivan@81: timesig = [4,2,24,8]; ivan@81: end ivan@81: ivan@81: tracks = unique(M(:,1)); ivan@81: Ntracks = length(tracks); ivan@81: ivan@81: % start building 'midi' struct ivan@81: ivan@81: if (Ntracks==1) ivan@81: midi.format = 0; ivan@81: else ivan@81: midi.format = 1; ivan@81: end ivan@81: ivan@81: midi.ticks_per_quarter_note = ticks_per_quarter_note; ivan@81: ivan@81: tempo = 500000; % could be set by user, etc... ivan@81: % (microsec per quarter note) ivan@81: ivan@81: for i=1:Ntracks ivan@81: ivan@81: trM = M(i==M(:,1),:); ivan@81: ivan@81: note_events_onoff = []; ivan@81: note_events_n = []; ivan@81: note_events_ticktime = []; ivan@81: ivan@81: % gather all the notes: ivan@81: for j=1:size(trM,1) ivan@81: % note on event: ivan@81: note_events_onoff(end+1) = 1; ivan@81: note_events_n(end+1) = j; ivan@81: note_events_ticktime(end+1) = 1e6 * trM(j,5) * ticks_per_quarter_note / tempo; ivan@81: ivan@81: % note off event: ivan@81: note_events_onoff(end+1) = 0; ivan@81: note_events_n(end+1) = j; ivan@81: note_events_ticktime(end+1) = 1e6 * trM(j,6) * ticks_per_quarter_note / tempo; ivan@81: end ivan@81: ivan@81: ivan@81: msgCtr = 1; ivan@81: ivan@81: % set tempo... ivan@81: midi.track(i).messages(msgCtr).deltatime = 0; ivan@81: midi.track(i).messages(msgCtr).type = 81; ivan@81: midi.track(i).messages(msgCtr).midimeta = 0; ivan@81: midi.track(i).messages(msgCtr).data = encode_int(tempo,3); ivan@81: midi.track(i).messages(msgCtr).chan = []; ivan@81: msgCtr = msgCtr + 1; ivan@81: ivan@81: % set time sig... ivan@81: midi.track(i).messages(msgCtr).deltatime = 0; ivan@81: midi.track(i).messages(msgCtr).type = 88; ivan@81: midi.track(i).messages(msgCtr).midimeta = 0; ivan@81: midi.track(i).messages(msgCtr).data = timesig(:); ivan@81: midi.track(i).messages(msgCtr).chan = []; ivan@81: msgCtr = msgCtr + 1; ivan@81: ivan@81: [junk,ord] = sort(note_events_ticktime); ivan@81: ivan@81: prevtick = 0; ivan@81: for j=1:length(ord) ivan@81: ivan@81: n = note_events_n(ord(j)); ivan@81: cumticks = note_events_ticktime(ord(j)); ivan@81: ivan@81: midi.track(i).messages(msgCtr).deltatime = cumticks - prevtick; ivan@81: midi.track(i).messages(msgCtr).midimeta = 1; ivan@81: midi.track(i).messages(msgCtr).chan = trM(n,2); ivan@81: midi.track(i).messages(msgCtr).used_running_mode = 0; ivan@81: ivan@81: if (note_events_onoff(ord(j))==1) ivan@81: % note on: ivan@81: midi.track(i).messages(msgCtr).type = 144; ivan@81: midi.track(i).messages(msgCtr).data = [trM(n,3); trM(n,4)]; ivan@81: else ivan@81: %-- note off msg: ivan@81: %midi.track(i).messages(msgCtr).type = 128; ivan@81: %midi.track(i).messages(msgCtr).data = [trM(n,3); trM(n,4)]; ivan@81: %-- note on vel=0: ivan@81: midi.track(i).messages(msgCtr).type = 144; ivan@81: midi.track(i).messages(msgCtr).data = [trM(n,3); 0]; ivan@81: end ivan@81: msgCtr = msgCtr + 1; ivan@81: ivan@81: prevtick = cumticks; ivan@81: end ivan@81: ivan@81: % end of track: ivan@81: midi.track(i).messages(msgCtr).deltatime = 0; ivan@81: midi.track(i).messages(msgCtr).type = 47; ivan@81: midi.track(i).messages(msgCtr).midimeta = 0; ivan@81: midi.track(i).messages(msgCtr).data = []; ivan@81: midi.track(i).messages(msgCtr).chan = []; ivan@81: msgCtr = msgCtr + 1; ivan@81: ivan@81: end ivan@81: ivan@81: ivan@81: % return a _column_ vector ivan@81: % (copied from writemidi.m) ivan@81: function A=encode_int(val,Nbytes) ivan@81: ivan@81: A = zeros(Nbytes,1); %ensure col vector (diff from writemidi.m...) ivan@81: for i=1:Nbytes ivan@81: A(i) = bitand(bitshift(val, -8*(Nbytes-i)), 255); ivan@81: end ivan@81: