Home > utils > read_mid.m

read_mid

PURPOSE ^

midinfo = read_mid(fname);

SYNOPSIS ^

function midi = read_mid(fname)

DESCRIPTION ^

 midinfo = read_mid(fname);

 Read information in a text dump of a multitrack MIDI file
 The text dump is formatted by MIDI to Csound on a Mac.

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SOURCE CODE ^

0001 function midi = read_mid(fname)
0002 % midinfo = read_mid(fname);
0003 %
0004 % Read information in a text dump of a multitrack MIDI file
0005 % The text dump is formatted by MIDI to Csound on a Mac.
0006 %
0007 
0008 % 3/18/01 PJ
0009 %
0010 % 8/3/01 PJ - changed from a structure with field arrays to a structure array
0011 %             with scalar fields.  This will hopefully increase the speed of
0012 %             reading .mid files.
0013 %
0014 % 08/09/01 PJ - Added fname to midi structure
0015 
0016 if nargin < 1
0017   error('Please provide a filename')
0018 end
0019 
0020 fid = fopen(fname,'rt');
0021 if fid < 0
0022   error(lasterr)
0023 end
0024 
0025 % Count the number of lines in the file and size the midi structure to
0026 % accommodate all lines.  Delete unfilled lines later
0027 
0028 disp('Counting the number of lines in the file');
0029 num_lines = 0;
0030 while ~feof(fid)
0031   fgetl(fid);
0032   num_lines = num_lines+1;
0033 end
0034 disp(sprintf('\nFound %d lines', num_lines))
0035 
0036 % Initialize the midi structure and various arrays
0037 disp('Creating structure to hold midi information ...')
0038 %midi = struct('fname', '', 'track_names',{}, 'takt', [], 'onoff', [], ...
0039 %    'pitch', [], 'vel', [], 'ctl_id', [], 'ctl_val', []);
0040 
0041 track = zeros(num_lines,1);
0042 takt = zeros(num_lines,1);
0043 onoff = zeros(num_lines,1);
0044 pitch = zeros(num_lines,1);
0045 vel = zeros(num_lines,1);
0046 ctl_id = zeros(num_lines,1);
0047 ctl_val = zeros(num_lines,1);
0048 
0049 disp(sprintf('Starting to read events'))
0050 frewind(fid);
0051 curr_track = 0;
0052 ce = 0;
0053 while ~feof(fid)
0054   lstr = fgetl(fid);
0055   [h count, errmsg, nextidx] = sscanf(lstr,'%s',1);
0056   switch(h)
0057     case 'Header:'
0058       targ_str = '#tracks';
0059       num_tracks = sscanf(lstr(findstr(lstr,targ_str)+length(targ_str):end),'%d',1);
0060       disp(sprintf('Detected %d tracks', num_tracks))
0061       
0062       targ_str = 'division';
0063       qrt_gran = sscanf(lstr(findstr(lstr,targ_str)+length(targ_str):end),'%d',1);
0064       disp(sprintf('Quarter note granularity: %d', qrt_gran))
0065     case '***'                % track start/stop marker
0066       is_start = findstr(lstr, 'start');
0067       if is_start
0068     curr_track = curr_track+1;
0069     disp(sprintf('Detected start of track %d', curr_track))
0070       end
0071     case 'Text'            % try to read track name
0072       lidx = findstr(lstr,'<') + 1;
0073       ridx = findstr(lstr,'>') - 1;
0074       track_names{curr_track} = lstr(lidx:ridx);
0075       disp(sprintf('Track name: %s', lstr(lidx:ridx)))
0076     otherwise
0077       if findstr(lstr, 'Tempo')
0078     tempo = sscanf(lstr(max(find(isspace(lstr))):end),'%d',1)/1000;
0079     disp(sprintf('Tempo (ms/qrt_note): %d', tempo))
0080       elseif findstr(lstr,'Note')
0081     ce = ce+1;
0082 
0083     track(ce) = curr_track;
0084     takt(ce) =  sscanf(lstr,'%d',1); % get timing
0085     
0086     if findstr(lstr,'Note on')
0087       onoff(ce) = 1;
0088     else
0089       onoff(ce) = 0;
0090     end
0091     
0092     targ_str = 'pitch';
0093     pitch(ce) = sscanf(lstr(findstr(lstr,targ_str)+length(targ_str):end),'%d',1);
0094     targ_str = 'vel';
0095     vel(ce) = sscanf(lstr(findstr(lstr,targ_str)+length(targ_str):end),'%d',1);
0096       elseif findstr(lstr, 'Ctl chg')
0097     ce = ce+1;
0098     track(ce) = curr_track;
0099     takt(ce) =  sscanf(lstr,'%d',1); % get timing
0100     
0101     targ_str = 'ctl';
0102     ctl_id(ce) = sscanf(lstr(findstr(lstr,targ_str)+length(targ_str):end),'%d',1);
0103     targ_str = 'val';
0104     ctl_val(ce) = sscanf(lstr(findstr(lstr,targ_str)+length(targ_str):end),'%d',1);
0105     if ctl_val(ce)
0106       onoff(ce) = 1;
0107     else
0108       onoff(ce) = 0;
0109     end
0110       end
0111   end
0112 end
0113 
0114 disp(sprintf('Found a total of %d events', ce));
0115 
0116 if ce < num_lines
0117   track(ce+1:end) = [];
0118   takt(ce+1:end) = [];
0119   onoff(ce+1:end) = [];
0120   pitch(ce+1:end) = [];
0121   vel(ce+1:end) = [];
0122   ctl_id(ce+1:end) = [];
0123   ctl_val(ce+1:end) = [];
0124 end
0125 
0126 disp('Creating final midi structure')
0127 midi.fname = fname;
0128 midi.tempo = tempo;
0129 midi.qrt_gran = qrt_gran;
0130 midi.track_names = track_names;
0131 midi.track = track;
0132 midi.takt = takt;
0133 midi.onoff = onoff;
0134 midi.pitch = pitch;
0135 midi.vel = vel;
0136 midi.ctl_id = ctl_id;
0137 midi.ctl_val = ctl_val;
0138 
0139 %midi.event_info = struct('track', track, 'takt', takt, 'onoff', onoff, ...
0140 %    'pitch', pitch, 'vel', vel, 'ctl_id', ctl_id, 'ctl_val', ctl_val);
0141 
0142 fclose(fid);

Generated on Wed 20-Sep-2023 04:00:50 by m2html © 2003