protected void Open() { MidiFileReader = File.Open(filepath, FileMode.Open); ParseHeaderChunk(); while (MidiFileReader.Position < MidiFileReader.Length) { try { ParseTrackChunk(); } catch { if (trackBeginnings.Count == 0) { throw new Exception("Corrupt first track chunk header"); } else { ParseStatusText = "Chunk " + (trackcount - 1) + " has corrupt length\nCalculating length..."; var pos = trackBeginnings.Last(); var reader = new BufferByteReader(MidiFileReader, 10000, pos, MidiFileReader.Length - pos); try { var len = MIDITrackParser.GetCorruptChunkLength(reader); trackLengths[trackLengths.Count - 1] = (uint)len; MidiFileReader.Position = pos + len; } catch { throw new Exception("Could not determine length of corrupt chunk"); } } } ParseNumber += 2; cancel.ThrowIfCancellationRequested(); } parsers = new MIDITrackParser[trackcount]; }
protected void FirstPassParse() { object l = new object(); int tracksParsed = 0; ParseStage = ParsingStage.FirstPass; Parallel.For(0, parsers.Length, new ParallelOptions() { CancellationToken = cancel }, (i) => { var reader = new BufferByteReader(MidiFileReader, 100000, trackBeginnings[i], trackLengths[i]); parsers[i] = new MIDITrackParser(reader, division, i, loaderSettings); parsers[i].FirstPassParse(); lock (l) { tracksParsed++; ParseNumber += 20; ParseStatusText = "Analyzing MIDI\nTracks " + tracksParsed + " of " + parsers.Length; Console.WriteLine("Pass 1 Parsed track " + tracksParsed + "/" + parsers.Length); if (FirstKey > parsers[i].FirstKey) { FirstKey = parsers[i].FirstKey; } if (LastKey < parsers[i].LastKey) { LastKey = parsers[i].LastKey; } } }); cancel.ThrowIfCancellationRequested(); var temposMerge = TimedMerger <TempoEvent> .MergeMany(parsers.Select(p => p.Tempos).ToArray(), t => t.time); globalTempos = temposMerge.Cast <TempoEvent>().ToArray(); MidiNoteCount = parsers.Select(p => p.noteCount).Sum(); }