示例#1
0
 internal Iterator(FastList <T> ll)
 {
     _ilist = ll;
     Reset();
 }
示例#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;
        }
示例#3
0
        public void ParseNextEvent()
        {
            try
            {
                if (!readDelta)
                {
                    trackTime += ReadVariableLen();
                }
                readDelta = false;

                double time = trackTime;
                if (timebase)
                {
                    time = trackFlexTime;
                }

                byte command = reader.ReadFast();
                if (command < 0x80)
                {
                    reader.Pushback = command;
                    command         = prevCommand;
                }
                prevCommand = command;
                byte comm = (byte)(command & 0b11110000);
                if (comm == 0b10010000)
                {
                    byte channel = (byte)(command & 0b00001111);
                    byte note    = reader.Read();
                    byte vel     = reader.ReadFast();

                    if (settings.playbackEnabled && vel > 10)
                    {
                        globalPlaybackEvents.Add(new PlaybackEvent()
                        {
                            pos = time,
                            val = command | (note << 8) | (vel << 16)
                        });
                    }
                    if (vel == 0)
                    {
                        var l = UnendedNotes[note << 4 | channel];
                        if (!l.ZeroLen)
                        {
                            Note n = l.Pop();
                            n.end      = time;
                            n.hasEnded = true;
                        }
                    }
                    else
                    {
                        Note n = new Note();
                        n.start   = time;
                        n.key     = note;
                        n.color   = trkColors[channel];
                        n.channel = channel;
                        n.vel     = vel;
                        n.track   = trackID;
                        if (UnendedNotes == null)
                        {
                            UnendedNotes = new FastList <Note> [256 * 16];
                            for (int i = 0; i < 256 * 16; i++)
                            {
                                UnendedNotes[i] = new FastList <Note>();
                            }
                        }
                        UnendedNotes[note << 4 | channel].Add(n);
                        globalDisplayNotes.Add(n);
                    }
                }
                else if (comm == 0b10000000)
                {
                    int  channel = command & 0b00001111;
                    byte note    = reader.Read();
                    byte vel     = reader.ReadFast();
                    var  l       = UnendedNotes[note << 4 | channel];
                    if (!l.ZeroLen)
                    {
                        try
                        {
                            Note n = l.Pop();

                            if (settings.playbackEnabled && n.vel > 10)
                            {
                                globalPlaybackEvents.Add(new PlaybackEvent()
                                {
                                    pos = time,
                                    val = command | (note << 8) | (vel << 16)
                                });
                            }
                            n.end      = time;
                            n.hasEnded = true;
                        }
                        catch
                        { }
                    }
                }
                else if (comm == 0b10100000)
                {
                    int  channel = command & 0b00001111;
                    byte note    = reader.Read();
                    byte vel     = reader.Read();
                    if (settings.playbackEnabled)
                    {
                        globalPlaybackEvents.Add(new PlaybackEvent()
                        {
                            pos = time,
                            val = command | (note << 8) | (vel << 16)
                        });
                    }
                }
                else if (comm == 0b11000000)
                {
                    int  channel = command & 0b00001111;
                    byte program = reader.Read();
                    if (settings.playbackEnabled)
                    {
                        globalPlaybackEvents.Add(new PlaybackEvent()
                        {
                            pos = time,
                            val = command | (program << 8)
                        });
                    }
                }
                else if (comm == 0b11010000)
                {
                    int  channel  = command & 0b00001111;
                    byte pressure = reader.Read();
                    if (settings.playbackEnabled)
                    {
                        globalPlaybackEvents.Add(new PlaybackEvent()
                        {
                            pos = time,
                            val = command | (pressure << 8)
                        });
                    }
                }
                else if (comm == 0b11100000)
                {
                    int  channel = command & 0b00001111;
                    byte l       = reader.Read();
                    byte m       = reader.Read();
                    if (settings.playbackEnabled)
                    {
                        globalPlaybackEvents.Add(new PlaybackEvent()
                        {
                            pos = time,
                            val = command | (l << 8) | (m << 16)
                        });
                    }
                }
                else if (comm == 0b10110000)
                {
                    int  channel = command & 0b00001111;
                    byte cc      = reader.Read();
                    byte vv      = reader.Read();
                    if (settings.playbackEnabled)
                    {
                        globalPlaybackEvents.Add(new PlaybackEvent()
                        {
                            pos = time,
                            val = command | (cc << 8) | (vv << 16)
                        });
                    }
                }
                else if (command == 0b11110000)
                {
                    while (reader.Read() != 0b11110111)
                    {
                        ;
                    }
                }
                else if (command == 0b11110100 || command == 0b11110001 || command == 0b11110101 || command == 0b11111001 || command == 0b11111101)
                {
                    //printf("Undefined\n");
                }
                else if (command == 0b11110010)
                {
                    int  channel = command & 0b00001111;
                    byte ll      = reader.Read();
                    byte mm      = reader.Read();
                }
                else if (command == 0b11110011)
                {
                    byte ss = reader.Read();
                }
                else if (command == 0b11110110)
                {
                }
                else if (command == 0b11110111)
                {
                }
                else if (command == 0b11111000)
                {
                }
                else if (command == 0b11111010)
                {
                }
                else if (command == 0b11111100)
                {
                }
                else if (command == 0b11111110)
                {
                }
                else if (command == 0xFF)
                {
                    command = reader.Read();
                    if (command == 0x00)
                    {
                        if (reader.Read() != 2)
                        {
                            throw new Exception("Corrupt Track");
                        }
                        reader.Read();
                        reader.Read();
                    }
                    else if (command == 0x01)
                    {
                        int    size = (int)ReadVariableLen();
                        char[] text = new char[size];
                        for (int i = 0; i < size; i++)
                        {
                            text[i] = (char)reader.Read();
                        }
                        string str = new string(text);
                    }
                    else if (command == 0x02)
                    {
                        int    size = (int)ReadVariableLen();
                        char[] text = new char[size];
                        for (int i = 0; i < size; i++)
                        {
                            text[i] = (char)reader.Read();
                        }
                        string str = new string(text);
                    }
                    else if (command == 0x03)
                    {
                        int    size = (int)ReadVariableLen();
                        char[] text = new char[size];
                        for (int i = 0; i < size; i++)
                        {
                            text[i] = (char)reader.Read();
                        }
                        string str = new string(text);
                    }
                    else if (command == 0x04)
                    {
                        int    size = (int)ReadVariableLen();
                        char[] text = new char[size];
                        for (int i = 0; i < size; i++)
                        {
                            text[i] = (char)reader.Read();
                        }
                        string str = new string(text);
                    }
                    else if (command == 0x05)
                    {
                        int    size = (int)ReadVariableLen();
                        char[] text = new char[size];
                        for (int i = 0; i < size; i++)
                        {
                            text[i] = (char)reader.Read();
                        }
                        string str = new string(text);
                    }
                    else if (command == 0x06)
                    {
                        int    size = (int)ReadVariableLen();
                        char[] text = new char[size];
                        for (int i = 0; i < size; i++)
                        {
                            text[i] = (char)reader.Read();
                        }
                        string str = new string(text);
                    }
                    else if (command == 0x07)
                    {
                        int    size = (int)ReadVariableLen();
                        char[] text = new char[size];
                        for (int i = 0; i < size; i++)
                        {
                            text[i] = (char)reader.Read();
                        }
                        string str = new string(text);
                    }
                    else if (command == 0x08)
                    {
                        int    size = (int)ReadVariableLen();
                        char[] text = new char[size];
                        for (int i = 0; i < size; i++)
                        {
                            text[i] = (char)reader.Read();
                        }
                        string str = new string(text);
                    }
                    else if (command == 0x09)
                    {
                        int    size = (int)ReadVariableLen();
                        char[] text = new char[size];
                        for (int i = 0; i < size; i++)
                        {
                            text[i] = (char)reader.Read();
                        }
                        string str = new string(text);
                    }
                    else if (command == 0x0A)
                    {
                        int    size = (int)ReadVariableLen();
                        byte[] data = new byte[size];
                        for (int i = 0; i < size; i++)
                        {
                            data[i] = reader.Read();
                        }
                        if (data.Length == 8 || data.Length == 12)
                        {
                            if (data[0] == 0x00 &&
                                data[1] == 0x0F)
                            {
                                Color4 col1 = new Color4(data[4], data[5], data[6], data[7]);
                                Color4 col2;
                                if (data.Length == 12)
                                {
                                    col2 = new Color4(data[8], data[9], data[10], data[11]);
                                }
                                else
                                {
                                    col2 = col1;
                                }
                                if (data[2] < 0x10 || data[2] == 0x7F)
                                {
                                    var c = new ColorChange()
                                    {
                                        pos = time, col1 = col1, col2 = col2, channel = data[2], track = this
                                    };
                                    globalColorEvents.Add(c);
                                }
                            }
                        }
                    }
                    else if (command == 0x20)
                    {
                        command = reader.Read();
                        if (command != 1)
                        {
                            throw new Exception("Corrupt Track");
                        }
                        channelPrefix = reader.Read();
                    }
                    else if (command == 0x21)
                    {
                        command = reader.Read();
                        if (command != 1)
                        {
                            throw new Exception("Corrupt Track");
                        }
                        reader.Skip(1);
                        //TODO:  MIDI port
                    }
                    else if (command == 0x2F)
                    {
                        command = reader.Read();
                        if (command != 0)
                        {
                            throw new Exception("Corrupt Track");
                        }
                        EndTrack();
                    }
                    else if (command == 0x51)
                    {
                        command = reader.Read();
                        if (command != 3)
                        {
                            throw new Exception("Corrupt Track");
                        }
                        int btempo = 0;
                        for (int i = 0; i != 3; i++)
                        {
                            btempo = (int)((btempo << 8) | reader.Read());
                        }
                        if (!timebase)
                        {
                            Tempo t = new Tempo();
                            t.pos   = trackTime;
                            t.tempo = btempo;

                            lock (globalTempoEvents)
                            {
                                globalTempoEvents.Add(t);
                            }
                        }
                        midi.tempoTickMultiplier = ((double)midi.division / btempo) * 1000;
                    }
                    else if (command == 0x54)
                    {
                        command = reader.Read();
                        if (command != 5)
                        {
                            throw new Exception("Corrupt Track");
                        }
                        reader.Skip(4);
                    }
                    else if (command == 0x58)
                    {
                        command = reader.Read();
                        if (command != 4)
                        {
                            throw new Exception("Corrupt Track");
                        }
                        reader.Skip(4);
                    }
                    else if (command == 0x59)
                    {
                        command = reader.Read();
                        if (command != 2)
                        {
                            throw new Exception("Corrupt Track");
                        }
                        reader.Skip(2);
                        //TODO: Key Signature
                    }
                    else if (command == 0x7F)
                    {
                        int    size = (int)ReadVariableLen();
                        byte[] data = new byte[size];
                        for (int i = 0; i < size; i++)
                        {
                            data[i] = reader.Read();
                        }
                    }
                    else
                    {
                        throw new Exception("Corrupt Track");
                    }
                }
                else
                {
                    throw new Exception("Corrupt Track");
                }
            }