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(); }
void SecondPassParse() { object l = new object(); int tracksParsed = 0; ParseStage = ParsingStage.SecondPass; Parallel.For(0, parsers.Length, (i) => { parsers[i].SecondPassParse(); lock (l) { tracksParsed++; ParseNumber += 20; ParseStatusText = "Loading MIDI\nTracks " + tracksParsed + " of " + parsers.Length; Console.WriteLine("Pass 2 Parsed track " + tracksParsed + "/" + parsers.Length); } }); cancel.ThrowIfCancellationRequested(); int keysMerged = 0; var eventMerger = Task.Run(() => { int count = loaderSettings.EventPlayerThreads; MIDINoteEvents = new MIDIEvent[count][]; Parallel.For(0, count, new ParallelOptions() { CancellationToken = cancel }, i => { try { MIDINoteEvents[i] = TimedMerger <MIDIEvent> .MergeMany(parsers.Select(p => new SkipIterator <MIDIEvent>(p.NoteEvents, i, count)).ToArray(), e => { return(e.time); }).ToArray(); } catch (OperationCanceledException) { } }); }); var controlEventMerger = Task.Run(() => { int count = loaderSettings.EventPlayerThreads; MIDIControlEvents = TimedMerger <MIDIEvent> .MergeMany(parsers.Select(p => p.ControlEvents).ToArray(), e => e.time).ToArray(); }); cancel.ThrowIfCancellationRequested(); ParseStage = ParsingStage.MergingKeys; long noteCount = 0; Parallel.For(0, 256, new ParallelOptions() { CancellationToken = cancel }, (i) => { var en = TimedMerger <Note> .MergeMany(parsers.Select(p => p.Notes[i]).ToArray(), n => n.start); if (loaderSettings.RemoveOverlaps) { Notes[i] = RemoveOverlaps(en).ToArray(); } else { Notes[i] = en.ToArray(); } foreach (var p in parsers) { p.Notes[i] = null; } lock (l) { noteCount += Notes[i].Length; keysMerged++; ParseNumber += 10; ParseStatusText = "Merging Notes\nMerged keys " + keysMerged + " of " + 256; Console.WriteLine("Merged key " + keysMerged + "/" + 256); } }); MidiNoteCount = noteCount; List <ColorEvent[]> ce = new List <ColorEvent[]>(); foreach (var p in parsers) { ce.AddRange(p.ColorEvents); } ColorEvents = ce.ToArray(); cancel.ThrowIfCancellationRequested(); ParseStatusText = "Merging Events..."; ParseStage = ParsingStage.MergingEvents; Console.WriteLine("Merging events..."); controlEventMerger.GetAwaiter().GetResult(); eventMerger.GetAwaiter().GetResult(); ParseStatusText = "Done!"; }