Mercurial > hg > smallbox
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/util/matlab_midi/writemidi.m Mon Mar 28 17:35:01 2011 +0100 @@ -0,0 +1,143 @@ +function rawbytes=writemidi(midi,filename,do_run_mode) +% rawbytes=writemidi(midi,filename,do_run_mode) +% +% writes to a midi file +% +% midi is a structure like that created by readmidi.m +% +% do_run_mode: flag - use running mode when possible. +% if given, will override the msg.used_running_mode +% default==0. (1 may not work...) +% +% TODO: use note-on for note-off... (for other function...) +% + +% Copyright (c) 2009 Ken Schutte +% more info at: http://www.kenschutte.com/midi + + +%if (nargin<3) +do_run_mode = 0; +%end + + +% do each track: +Ntracks = length(midi.track); + +for i=1:Ntracks + + databytes_track{i} = []; + + for j=1:length(midi.track(i).messages) + + msg = midi.track(i).messages(j); + + msg_bytes = encode_var_length(msg.deltatime); + + if (msg.midimeta==1) + + % check for doing running mode + run_mode = 0; + run_mode = msg.used_running_mode; + + % should check that prev msg has same type to allow run + % mode... + + + % if (j>1 && do_run_mode && msg.type == midi.track(i).messages(j-1).type) +% run_mode = 1; +% end + + +msg_bytes = [msg_bytes; encode_midi_msg(msg, run_mode)]; + + + else + + msg_bytes = [msg_bytes; encode_meta_msg(msg)]; + + end + +% disp(msg_bytes') + +%if (msg_bytes ~= msg.rawbytes) +% error('rawbytes mismatch'); +%end + + databytes_track{i} = [databytes_track{i}; msg_bytes]; + + end +end + + +% HEADER +% double('MThd') = [77 84 104 100] +rawbytes = [77 84 104 100 ... + 0 0 0 6 ... + encode_int(midi.format,2) ... + encode_int(Ntracks,2) ... + encode_int(midi.ticks_per_quarter_note,2) ... + ]'; + +% TRACK_CHUCKS +for i=1:Ntracks + a = length(databytes_track{i}); + % double('MTrk') = [77 84 114 107] + tmp = [77 84 114 107 ... + encode_int(length(databytes_track{i}),4) ... + databytes_track{i}']'; + rawbytes(end+1:end+length(tmp)) = tmp; +end + + +% write to file +fid = fopen(filename,'w'); +%fwrite(fid,rawbytes,'char'); +fwrite(fid,rawbytes,'uint8'); +fclose(fid); + +% return a _column_ vector +function A=encode_int(val,Nbytes) + +for i=1:Nbytes + A(i) = bitand(bitshift(val, -8*(Nbytes-i)), 255); +end + + +function bytes=encode_var_length(val) + +binStr = dec2base(round(val),2); +Nbytes = ceil(length(binStr)/7); + +binStr = ['00000000' binStr]; +bytes = []; +for i=1:Nbytes + if (i==1) + lastbit = '0'; + else + lastbit = '1'; + end + B = bin2dec([lastbit binStr(end-i*7+1:end-(i-1)*7)]); + bytes = [B; bytes]; +end + + +function bytes=encode_midi_msg(msg, run_mode) + +bytes = []; + +if (run_mode ~= 1) + bytes = msg.type; + % channel: + bytes = bytes + msg.chan; % lower nibble should be chan +end + +bytes = [bytes; msg.data]; + +function bytes=encode_meta_msg(msg) + +bytes = 255; +bytes = [bytes; msg.type]; +bytes = [bytes; encode_var_length(length(msg.data))]; +bytes = [bytes; msg.data]; +