コード例 #1
0
        public void HandleEvent(int track, MidiEvent e)
        {
            if (e.status == 0xff && e.type == 0x51)                // meta tempo
            {
                int i = e.dataLoc;
                // 24-bit value specifying the tempo as the number of microseconds per beat
                int microsecondsPerBeat = BitBe.ReadInt24(file.bytes, ref i);
                beatsPerSecond = (1000000f / microsecondsPerBeat);
                Debug.LogFormat("meta: {0} tempo", microsecondsPerBeat);
            }

            byte channel = (byte)(e.status & 0xf);

            DispatchChannelEvent(channel, e.status, e.b1, e.b2);

            for (int i = 0, count = routes.Count; i < count; i += 1)
            {
                var r = routes[i];
                if (r.trackIn == track && r.channelIn == channel)
                {
                    DispatchChannelEvent(r.channelOut, e.status, e.b1, e.b2);
                }
            }
        }
コード例 #2
0
        void Parse()
        {
            var seq = new Sequence();

            // default tempo 120 bpm
            float beatsPerSecond = 2;
            int   ticks          = 0;
            float seconds        = 0;

            byte[] channelPrograms = new byte[16];

            for (int i = 0; i < file.combinedTrack.Length; i++)
            {
                var  e       = file.combinedTrack[i];
                byte channel = (byte)(e.status & 0xf);
                seq = SwitchWorkingSequence(seq, e.track, channel, channelPrograms[channel]);
                int tickDiff = e.tick - ticks;
                ticks    = e.tick;
                seconds += tickDiff / (beatsPerSecond * file.ticksPerBeat);


                switch (e.status >> 4)
                {
                case 0x8:                          // note off
                    //UnityEngine.Debug.LogFormat("off {3} track {0} tick {1} seconds {2}", e.track, e.tick, seconds, e.b1);
                    NoteOff(seq, e.tick, seconds, e.b1);
                    break;

                case 0x9:                          // note on
                    //UnityEngine.Debug.LogFormat("on {3} track {0} tick {1} seconds {2}", e.track, e.tick, seconds, e.b1);
                    if (e.b2 == 0)
                    {
                        NoteOff(seq, e.tick, seconds, e.b1);
                    }
                    else
                    {
                        seq.notes.Add(new Note {
                            track = e.track, channel = channel, note = e.b1, velocity = e.b2, start = e.tick, startSeconds = seconds
                        });
                    }
                    break;

                case 0xc:                          // program change
                    //UnityEngine.Debug.LogFormat("prog track {0} tick {1} seconds {2}", e.track, e.tick, seconds);
                    channelPrograms[channel] = e.b1;
                    seq = SwitchWorkingSequence(seq, e.track, seq.channel, e.b1);
                    break;

                case 0xff:                          // meta
                    if (e.type == 0x51)             // tempo
                    //UnityEngine.Debug.LogFormat("temp track {0} tick {1} seconds {2}", e.track, e.tick, seconds);
                    {
                        int start = e.dataLoc;
                        // 24-bit value specifying the tempo as the number of microseconds per beat
                        int microsecondsPerBeat = BitBe.ReadInt24(file.bytes, ref start);
                        beatsPerSecond = 1000000f / microsecondsPerBeat;
                    }
                    break;
                }
            }

            if (seq.notes.Count > 0 && !sequences.Contains(seq))
            {
                sequences.Add(seq);
            }
            sequences.Sort((a, b) => {
                if (a.track == b.track)
                {
                    if (a.channel == b.channel)
                    {
                        return(a.program.CompareTo(b.program));
                    }
                    return(a.channel.CompareTo(b.channel));
                }
                return(a.track.CompareTo(b.track));
            });

            int  trackGroupIndex   = 0;
            byte channelGroupIndex = 0;
            byte programGroupIndex = 0;
            var  trackGroupDict    = new Dictionary <int, int>();
            var  channelGroupDict  = new Dictionary <byte, byte>();
            var  programGroupDict  = new Dictionary <byte, byte>();

            start = end = -1;
            for (int i = 0; i < sequences.Count; i++)
            {
                seq = sequences[i];

                if (!trackGroupDict.ContainsKey(seq.track))
                {
                    trackGroupDict.Add(seq.track, trackGroupIndex);
                    trackGroupIndex += 1;
                }
                if (!channelGroupDict.ContainsKey(seq.channel))
                {
                    channelGroupDict.Add(seq.channel, channelGroupIndex);
                    channelGroupIndex += 1;
                }
                if (!programGroupDict.ContainsKey(seq.program))
                {
                    programGroupDict.Add(seq.program, programGroupIndex);
                    programGroupIndex += 1;
                }
                seq.trackGroup   = trackGroupDict[seq.track];
                seq.channelGroup = channelGroupDict[seq.channel];
                seq.programGroup = programGroupDict[seq.program];

                noteCount += seq.notes.Count;

                seq.start = seq.notes[0].start;
                if (start == -1 || seq.start < start)
                {
                    start = seq.start;
                }
                int seqEnd = seq.notes[0].end;
                for (int j = 0; j < seq.notes.Count; j++)
                {
                    var n = seq.notes[j];
                    if (seqEnd < n.end)
                    {
                        seqEnd = n.end;
                    }
                    if (n.end == 0)
                    {
                        UnityEngine.Debug.LogErrorFormat("Note is never off: {0} tr {1} ch {2} start {3} seq {4} tr {5} ch {6} prog {7}",
                                                         n.note, n.track, n.channel, n.start, seq.index, seq.track, seq.channel, seq.program);
                    }
                }
                seq.end = seqEnd;
                if (end == -1 || seq.end > end)
                {
                    end = seq.end;
                }
            }

            trackGroups   = trackGroupDict.Keys.ToArray();
            channelGroups = channelGroupDict.Keys.ToArray();
            programGroups = programGroupDict.Keys.ToArray();
        }