public void parse(MidiFileReader file, string filename)
{
string id;
int len;
this.filename = filename;
tracks = new List<MidiTrack>();
trackPerChannel = false;
id = file.ReadAscii(4);
if (id != "MThd") {
throw new MidiFileException("Doesn't start with MThd", 0);
}
len = file.ReadInt();
if (len != 6) {
throw new MidiFileException("Bad MThd header", 4);
}
trackmode = file.ReadShort();
int num_tracks = file.ReadShort();
quarternote = file.ReadShort();
events = new List<MidiEvent>[num_tracks];
for (int tracknum = 0; tracknum < num_tracks; tracknum++) {
events[tracknum] = ReadTrack(file);
MidiTrack track = new MidiTrack(events[tracknum], tracknum);
if (track.Notes.Count > 0) {
tracks.Add(track);
}
}
/* Get the length of the song in pulses */
foreach (MidiTrack track in tracks) {
MidiNote last = track.Notes[track.Notes.Count-1];
if (this.totalpulses < last.StartTime + last.Duration) {
this.totalpulses = last.StartTime + last.Duration;
}
}
/* If we only have one track with multiple channels, then treat
* each channel as a separate track.
*/
if (tracks.Count == 1 && HasMultipleChannels(tracks[0])) {
tracks = SplitChannels(tracks[0], events[tracks[0].Number]);
trackPerChannel = true;
}
CheckStartTimes(tracks);
/* Determine the time signature */
int tempo = 0;
int numer = 0;
int denom = 0;
foreach (List<MidiEvent> list in events) {
foreach (MidiEvent mevent in list) {
if (mevent.Metaevent == MetaEventTempo && tempo == 0) {
tempo = mevent.Tempo;
}
if (mevent.Metaevent == MetaEventTimeSignature && numer == 0) {
numer = mevent.Numerator;
denom = mevent.Denominator;
}
}
}
if (tempo == 0) {
tempo = 500000; /* 500,000 microseconds = 0.05 sec */
}
if (numer == 0) {
numer = 4; denom = 4;
}
timesig = new TimeSignature(numer, denom, quarternote, tempo);
}