public MidiTrack(int id, BufferByteReader reader, MidiFile file, RenderSettings settings) { this.settings = settings; globalDisplayNotes = file.globalDisplayNotes; globalTempoEvents = file.globalTempoEvents; globalColorEvents = file.globalColorEvents; globalPlaybackEvents = file.globalPlaybackEvents; midi = file; this.reader = reader; trackID = id; ResetColors(); zeroTickTrkColors = new NoteColor[16]; for (int i = 0; i < 16; i++) { zeroTickTrkColors[i] = null; } }
public void LoadAndParseAll(bool useBufferStream = false) { long[] tracklens = new long[tracks.Length]; int p = 0; List <FastList <Tempo> > tempos = new List <FastList <Tempo> >(); Parallel.For(0, tracks.Length, (i) => { var reader = new BufferByteReader(MidiFileReader, settings.maxTrackBufferSize, trackBeginnings[i], trackLengths[i]); tracks[i] = new MidiTrack(i, reader, this, settings); var t = tracks[i]; while (!t.trackEnded) { try { t.ParseNextEventFast(); } catch { break; } } noteCount += t.noteCount; tracklens[i] = t.trackTime; if (t.foundTimeSig != null) { info.timeSig = t.foundTimeSig; } if (t.zerothTempo != -1) { zerothTempo = t.zerothTempo; } lock (tempos) tempos.Add(t.TempoEvents); t.Reset(); Console.WriteLine("Loaded track " + p++ + "/" + tracks.Length); GC.Collect(); }); maxTrackTime = tracklens.Max(); Console.WriteLine("Processing Tempos"); LinkedList <Tempo> Tempos = new LinkedList <Tempo>(); var iters = tempos.Select(t => t.GetEnumerator()).ToArray(); bool[] unended = new bool[iters.Length]; for (int i = 0; i < iters.Length; i++) { unended[i] = iters[i].MoveNext(); } while (true) { long smallest = 0; bool first = true; int id = 0; for (int i = 0; i < iters.Length; i++) { if (!unended[i]) { continue; } if (first) { smallest = iters[i].Current.pos; id = i; first = false; continue; } if (iters[i].Current.pos < smallest) { smallest = iters[i].Current.pos; id = i; } } if (first) { break; } Tempos.AddLast(iters[id].Current); unended[id] = iters[id].MoveNext(); } double time = 0; long ticks = maxTrackTime; double multiplier = ((double)500000 / division) / 1000000; long lastt = 0; foreach (var t in Tempos) { var offset = t.pos - lastt; time += offset * multiplier; ticks -= offset; lastt = t.pos; multiplier = ((double)t.tempo / division) / 1000000; } time += ticks * multiplier; info.secondsLength = time; maxTrackTime = tracklens.Max(); unendedTracks = trackcount; }