Example #1
0
    public static void appendFingeringToMidiFile(Midi.Sequence file, Fingering[] fingerings)
    {
        if (file.Count == 0)
        {
            Debug.LogWarning("MIDI no track found.");
            return;
        }

        var FingerMap = new Dictionary <int, Dictionary <int, Finger> >();

        foreach (var fingering in fingerings)
        {
            if (fingering.markers == null)
            {
                Debug.LogWarning("fingering markers is null.");
                continue;
            }

            foreach (var marker in fingering.markers)
            {
                if (!FingerMap.ContainsKey(marker.tick))
                {
                    FingerMap[marker.tick] = new Dictionary <int, Finger>();
                }

                FingerMap[marker.tick][marker.pitch] = marker.finger;
                //Debug.LogFormat("marker: {0}, {1}, {2}", marker.tick, marker.pitch, marker.finger);
            }
        }

        clearFingeringInMidiFile(file);

        foreach (Midi.Track track in file)
        {
            foreach (Midi.MidiEvent e in track.Iterator())
            {
                if (e.MidiMessage.MessageType == Midi.MessageType.Channel)
                {
                    Midi.ChannelMessage cm = e.MidiMessage as Midi.ChannelMessage;
                    if (cm.Command == Midi.ChannelCommand.NoteOn)
                    {
                        if (FingerMap.ContainsKey(e.AbsoluteTicks) && FingerMap[e.AbsoluteTicks].ContainsKey(cm.Data1))
                        {
                            Finger f = FingerMap[e.AbsoluteTicks][cm.Data1];

                            string marker = string.Format("finger:{0}|{1}", cm.Data1, (int)f);

                            track.Insert(e.AbsoluteTicks, new Midi.MetaMessage(Midi.MetaType.Marker, Encoding.Default.GetBytes(marker)));
                        }
                    }
                }
            }
        }

        file[0].Insert(0, new Midi.MetaMessage(Midi.MetaType.Text, Encoding.Default.GetBytes(MidiSignatureText)));
    }
Example #2
0
        public MIDIPlayback()
        {
            _MIDISequencer = new Midi.Sequencer();
            _MIDISequence  = new Midi.Sequence();

            // event handlers for various message types
            _MIDISequencer.ChannelMessagePlayed += sequencer_ChannelMessagePlayed;
            _MIDISequencer.Chased  += sequencer_Chased;
            _MIDISequencer.Stopped += sequencer_Stopped;
        }
Example #3
0
        public List <Note> MakeScore(string FilePath)
        {
            List <Note> Score = new List <Note>();

            MidiToolKit.Sequence sq = new MidiToolKit.Sequence();
            sq.Load(FilePath);

            Score = NoteMake(sq);

            return(Score);
        }
Example #4
0
    public static NotationTrack[] parseMidiFile(Midi.Sequence file)
    {
        NotationTrack[] tracks = new NotationTrack[file.Count];

        Regex fingerPattern = null;

        for (int i = 0; i < file.Count; ++i)
        {
            tracks[i] = parseMidiTrack(file[i], file.Division, ref fingerPattern);
        }

        return(tracks);
    }
Example #5
0
    public static void clearFingeringInMidiFile(Midi.Sequence file)
    {
        Regex signaturePattern = new Regex("^Fingering");
        Regex fingerPattern    = new Regex("^finger:");

        foreach (Midi.Track track in file)
        {
            System.Collections.Generic.List <int> toRemove = new System.Collections.Generic.List <int>();

            for (int i = track.Count - 1; i >= 0; --i)
            {
                Midi.MidiEvent e = track.GetMidiEvent(i);

                if (e.MidiMessage.MessageType == Midi.MessageType.Meta)
                {
                    Midi.MetaMessage msg = e.MidiMessage as Midi.MetaMessage;
                    switch (msg.MetaType)
                    {
                    case Midi.MetaType.Text:
                        if (signaturePattern.Match(Encoding.Default.GetString(msg.GetBytes())).Length > 0)
                        {
                            toRemove.Add(i);
                        }

                        break;

                    case Midi.MetaType.Marker:
                        if (fingerPattern.Match(Encoding.Default.GetString(msg.GetBytes())).Length > 0)
                        {
                            toRemove.Add(i);
                        }

                        break;
                    }
                }
            }

            foreach (int i in toRemove)
            {
                track.RemoveAt(i);
            }
        }
    }
Example #6
0
    public void load()
    {
        if (!SourceAsset)
        {
            Debug.LogError("SourceAsset is null.");
            return;
        }

        MemoryStream stream = new MemoryStream();

        stream.Write(SourceAsset.bytes, 0, SourceAsset.bytes.Length);
        stream.Position = 0;

        MidiSeq = new Midi.Sequence();
        MidiSeq.Load(stream);

        if (TrackHandIndices == null || TrackHandIndices.Length != MidiSeq.Count)
        {
            TrackHandIndices = Enumerable.Repeat(-1, MidiSeq.Count).ToArray();
        }

        Notation = NotationUtils.parseMidiFile(MidiSeq);
    }
Example #7
0
        private void ProcessMIDI()
        {
            Midi.Sequence _MIDISequence;

            // default MIDI tempos/milliseconds per tick
            int   tempo     = 500000;
            float msPerTick = (tempo / 48) / 1000.0f;

            _MIDISequence = new Midi.Sequence();
            _MIDISequence.Load(_sequence.MusicFile);

            if (_MIDISequence.SequenceType != Sanford.Multimedia.Midi.SequenceType.Ppqn)
            {
                MessageBox.Show("Unsupported MIDI type...sorry!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            foreach (Midi.Track t in _MIDISequence)
            {
                IEnumerator <Midi.MidiEvent> en = t.Iterator().GetEnumerator();

                while (en.MoveNext())
                {
                    Midi.MidiEvent e = en.Current;
                    switch (e.MidiMessage.MessageType)
                    {
                    // starta  new channel
                    case Sanford.Multimedia.Midi.MessageType.Channel:
                        Midi.ChannelMessage channel = (Midi.ChannelMessage)e.MidiMessage;

                        // if it's a note on command and it's in our mapping list
                        if (channel.Command == Sanford.Multimedia.Midi.ChannelCommand.NoteOn &&
                            _midiMap.ContainsKey(channel.MidiChannel) &&
                            (int)((e.AbsoluteTicks * msPerTick) / 50) < _sequence.Channels[_midiMap[channel.MidiChannel]].Data.Length)
                        {
                            // this means the note is on
                            if (channel.Data2 > 0)
                            {
                                _sequence.Channels[_midiMap[channel.MidiChannel]].Data[(int)((e.AbsoluteTicks * msPerTick) / 50)] = true;
                            }
                            else
                            {
                                // the note is off
                                _sequence.Channels[_midiMap[channel.MidiChannel]].Data[(int)((e.AbsoluteTicks * msPerTick) / 50)] = false;
                                if (chkHold.Checked)
                                {
                                    // backfill the grid
                                    for (int i = (int)((e.AbsoluteTicks * msPerTick) / 50); i > 0 && !_sequence.Channels[_midiMap[channel.MidiChannel]].Data[i]; i--)
                                    {
                                        _sequence.Channels[_midiMap[channel.MidiChannel]].Data[i] = true;
                                    }
                                }
                            }
                        }
                        // true note off...don't see this used much
                        if (channel.Command == Sanford.Multimedia.Midi.ChannelCommand.NoteOff &&
                            _midiMap.ContainsKey(channel.MidiChannel))
                        {
                            _sequence.Channels[_midiMap[channel.MidiChannel]].Data[(int)((e.AbsoluteTicks * msPerTick) / 50)] = false;
                            if (chkHold.Checked)
                            {
                                for (int i = (int)((e.AbsoluteTicks * msPerTick) / 50); i > 0 && !_sequence.Channels[_midiMap[channel.MidiChannel]].Data[i]; i--)
                                {
                                    _sequence.Channels[_midiMap[channel.MidiChannel]].Data[i] = true;
                                }
                            }
                        }
                        break;

                    case Sanford.Multimedia.Midi.MessageType.Meta:
                        Midi.MetaMessage meta = (Midi.MetaMessage)e.MidiMessage;
                        switch (meta.MetaType)
                        {
                        // again, get the tempo value
                        case Sanford.Multimedia.Midi.MetaType.Tempo:
                            tempo     = meta.GetBytes()[0] << 16 | meta.GetBytes()[1] << 8 | meta.GetBytes()[2];
                            msPerTick = (tempo / _MIDISequence.Division) / 1000.0f;
                            break;
                        }
                        break;
                    }
                }
            }
        }
Example #8
0
        private void GetMIDIInfo(string file, bool fillTime)
        {
            Midi.Sequence MIDISequence;

            int    tempo     = 500000;
            int    maxtick   = 0;
            float  msPerTick = (tempo / 48) / 1000.0f;
            string title     = string.Empty;

            _MIDIChannels = new BindingList <MIDIChannel>();

            // load the MIDI file
            MIDISequence = new Midi.Sequence();
            MIDISequence.Load(file);

            // we don't handle non-PPQN MIDI files
            if (MIDISequence.SequenceType != Sanford.Multimedia.Midi.SequenceType.Ppqn)
            {
                MessageBox.Show("Unsupported MIDI type...sorry!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            foreach (Midi.Track t in MIDISequence)
            {
                // get the command enumerator
                IEnumerator <Midi.MidiEvent> en = t.Iterator().GetEnumerator();
                bool channelAdded = false;
                while (en.MoveNext())
                {
                    Midi.MidiEvent e = en.Current;
                    switch (e.MidiMessage.MessageType)
                    {
                    case Sanford.Multimedia.Midi.MessageType.Channel:                                   // track the # of channels
                        Midi.ChannelMessage channel = (Midi.ChannelMessage)e.MidiMessage;
                        if (!channelAdded)
                        {
                            _MIDIChannels.Add(new MIDIChannel(channel.MidiChannel, title));
                            channelAdded = true;
                        }
                        break;

                    case Sanford.Multimedia.Midi.MessageType.Meta:
                        Midi.MetaMessage meta = (Midi.MetaMessage)e.MidiMessage;
                        switch (meta.MetaType)
                        {
                        // cache away the track name for the grid
                        case Sanford.Multimedia.Midi.MetaType.TrackName:
                            title = Encoding.ASCII.GetString(meta.GetBytes());
                            break;

                        // get the tempo and convert to a time value we can use
                        case Sanford.Multimedia.Midi.MetaType.Tempo:
                            tempo     = meta.GetBytes()[0] << 16 | meta.GetBytes()[1] << 8 | meta.GetBytes()[2];
                            msPerTick = (tempo / MIDISequence.Division) / 1000.0f;
                            break;
                        }
                        break;
                    }

                    // find the highest time value
                    if (e.AbsoluteTicks > maxtick)
                    {
                        maxtick = e.AbsoluteTicks;
                    }
                }
            }
            // and use that value to fill in the minutes/seconds
            if (fillTime)
            {
                txtMinutes.Text = (((int)(msPerTick * maxtick) / 1000) / 60).ToString();
                txtSeconds.Text = (((int)(msPerTick * maxtick) / 1000) % 60 + 1).ToString();
            }
        }
Example #9
0
        public List <Note> NoteMake(MidiToolKit.Sequence sq)
        {
            List <ChannelMessage> list_cm   = new List <ChannelMessage>();
            List <Note>           list_note = new List <Note>();

            ChannelMessage listcm = new ChannelMessage();

            //시퀀스를 트랙화
            foreach (MidiToolKit.Track track in sq)
            {
                //트렉안의 이벤트
                foreach (MidiToolKit.MidiEvent ev in track.Iterator())
                {
                    if (ev.MidiMessage is MidiToolKit.ChannelMessage cm)
                    {
                        switch (cm.Command)
                        {
                        case MidiToolKit.ChannelCommand.NoteOn:
                            if (cm.Data2 != 0)
                            {
                                ChannelMessage CM_struct = new ChannelMessage
                                {
                                    command      = "NoteOn",
                                    AbsoluteTick = ev.AbsoluteTicks,
                                    Value        = cm.Data1,
                                    velocuty     = cm.Data2
                                };

                                list_cm.Add(CM_struct);
                            }
                            else
                            {
                                listcm = list_cm.Find(x => x.Value.Equals(cm.Data1));
                                list_cm.Remove(new ChannelMessage()
                                {
                                    Value = cm.Data1, AbsoluteTick = listcm.AbsoluteTick, command = "NoteOn", velocuty = listcm.velocuty
                                });

                                list_note.Add(new Note((Byte)listcm.Value, (Byte)listcm.velocuty, listcm.AbsoluteTick, ev.AbsoluteTicks - listcm.AbsoluteTick));
                            }

                            break;

                        case MidiToolKit.ChannelCommand.NoteOff:
                            listcm = list_cm.Find(x => x.Value.Equals(cm.Data1));
                            list_cm.Remove(new ChannelMessage()
                            {
                                Value = cm.Data1, AbsoluteTick = listcm.AbsoluteTick, command = "NoteOn", velocuty = listcm.velocuty
                            });

                            list_note.Add(new Note((Byte)listcm.Value, (Byte)listcm.velocuty, listcm.AbsoluteTick, ev.AbsoluteTicks - listcm.AbsoluteTick));
                            break;
                        }
                    }
                }
            }

            //magenta에서 생성하는 미디의 PPQN을 현재 Song의 PPQN에 맞춰서 길이변화
            int Count = 0;

            foreach (Note i in list_note)
            {
                list_note[Count].Start  = (int)((double)i.Start * Song.Current.TimeResolution / sq.Division);
                list_note[Count].Length = (int)((double)i.Length * Song.Current.TimeResolution / sq.Division);
                if (list_note[Count].Velocity < 90)
                {
                    list_note[Count].Velocity = 90;
                }
                Count++;
            }

            return(list_note);
        }