예제 #1
0
        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;
            }
        }
예제 #2
0
        public void LoadAndParseAll(bool useBufferStream = false)
        {
            long[] tracklens = new long[tracks.Length];
            int    p         = 0;
            List <FastList <Tempo> > tempos = new List <FastList <Tempo> >();

            if (!settings.useMultithreadToLoadMidi)
            {
                // Parallel.For(0, tracks.Length, (i) =>
                for (int i = 0, trkLength = tracks.Length; i < trkLength; ++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();
                }// );
            }
            else
            {
                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");
            FastList <Tempo> Tempos = new FastList <Tempo>();
            var iters = tempos.Select(t => t.GetEnumerator()).ToArray();

            bool[] unended = new bool[iters.Length];
            for (int i = 0, itersLength = iters.Length; i < itersLength; ++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)
                for (int i = 0, itersLength = iters.Length; i < itersLength; ++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.Add(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;
        }