public GuitarTempo(GuitarMessageList owner, MidiEvent ev)
     : base(owner, ev, null, GuitarMessageType.GuitarTempo)
 {
     if (ev == null)
     {
         this.Tempo = Utility.DummyTempo;
     }
     else
     {
         var cb = new TempoChangeBuilder((MetaMessage)ev.Clone());
         this.Tempo = cb.Tempo;
     }
 }
Beispiel #2
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);
            }
        }
    }
        public GuitarTimeSignature(GuitarMessageList owner, MidiEvent ev)
            : base(owner, ev, null, GuitarMessageType.GuitarTimeSignature)
        {
            if (ev == null)
            {
                SetDownTick(0);
            }
            else
            {
                SetDownEvent(ev);

                var builder = new TimeSignatureBuilder((MetaMessage)ev.Clone());

                Numerator = builder.Numerator;
                Denominator = builder.Denominator;
                ClocksPerMetronomeClick = builder.ClocksPerMetronomeClick;

                ThirtySecondNotesPerQuarterNote = builder.ThirtySecondNotesPerQuarterNote;
            }
        }
Beispiel #4
0
        public void Move(MidiEvent e, int newPosition)
        {
            #region Require

            if (e.Owner != this)
            {
                throw new ArgumentException("MidiEvent does not belong to this Track.");
            }
            else if (newPosition < 0)
            {
                throw new ArgumentOutOfRangeException("newPosition");
            }
            else if (e == endOfTrackMidiEvent)
            {
                throw new InvalidOperationException(
                          "Cannot move end of track message. Use the EndOfTrackOffset property instead.");
            }

            #endregion

            MidiEvent previous = e.Previous;
            MidiEvent next     = e.Next;

            if (e.Previous != null && e.Previous.AbsoluteTicks > newPosition)
            {
                e.Previous.Next = e.Next;

                if (e.Next != null)
                {
                    e.Next.Previous = e.Previous;
                }

                while (previous != null && previous.AbsoluteTicks > newPosition)
                {
                    next     = previous;
                    previous = previous.Previous;
                }
            }
            else if (e.Next != null && e.Next.AbsoluteTicks < newPosition)
            {
                e.Next.Previous = e.Previous;

                if (e.Previous != null)
                {
                    e.Previous.Next = e.Next;
                }

                while (next != null && next.AbsoluteTicks < newPosition)
                {
                    previous = next;
                    next     = next.Next;
                }
            }

            if (previous != null)
            {
                previous.Next = e;
            }

            if (next != null)
            {
                next.Previous = e;
            }

            e.Previous = previous;
            e.Next     = next;
            e.SetAbsoluteTicks(newPosition);

            if (newPosition < head.AbsoluteTicks)
            {
                head = e;
            }

            if (newPosition > tail.AbsoluteTicks)
            {
                tail = e;
            }

            endOfTrackMidiEvent.SetAbsoluteTicks(Length);
            endOfTrackMidiEvent.Previous = tail;

            #region Invariant

            AssertValid();

            #endregion
        }
Beispiel #5
0
        /// <summary>
        /// Gets the MidiEvent at the specified index.
        /// </summary>
        /// <param name="index">
        /// The index of the MidiEvent to get.
        /// </param>
        /// <returns>
        /// The MidiEvent at the specified index.
        /// </returns>
        public MidiEvent GetMidiEvent(int index)
        {
            #region Require

            if (index < 0 || index >= Count)
            {
                throw new ArgumentOutOfRangeException("index", index,
                                                      "Track index out of range.");
            }

            #endregion

            MidiEvent result;

            if (index == Count - 1)
            {
                result = endOfTrackMidiEvent;
            }
            else
            {
                if (index < Count / 2)
                {
                    result = head;

                    for (int i = 0; i < index; i++)
                    {
                        result = result.Next;
                    }
                }
                else
                {
                    result = tail;

                    for (int i = Count - 2; i > index; i--)
                    {
                        result = result.Previous;
                    }
                }
            }

            #region Ensure

#if (DEBUG)
            if (index == Count - 1)
            {
                Debug.Assert(result.AbsoluteTicks == Length);
                Debug.Assert(result.MidiMessage == MetaMessage.EndOfTrackMessage);
            }
            else
            {
                MidiEvent t = head;

                for (int i = 0; i < index; i++)
                {
                    t = t.Next;
                }

                Debug.Assert(t == result);
            }
#endif

            #endregion

            return(result);
        }
Beispiel #6
0
 public ChannelMessageBuilder Initialize(MidiEvent ev)
 {
     this.message = ev.MessageData;
     return(this);
 }
 public SongUtilSearchResultItem(string trackName, MidiEvent ev)
 {
     this.Event = ev;
     this.TrackName = TrackName;
 }
Beispiel #8
0
        /// <summary>
        /// Inserts an IMidiMessage at the specified position in absolute ticks.
        /// </summary>
        /// <param name="position">
        /// The position in the Track in absolute ticks in which to insert the
        /// IMidiMessage.
        /// </param>
        /// <param name="message">
        /// The IMidiMessage to insert.
        /// </param>
        public void Insert(int position, IMidiMessage message)
        {
            #region Require

            if(position < 0)
            {
                throw new ArgumentOutOfRangeException("position", position,
                    "IMidiMessage position out of range.");
            }
            else if(message == null)
            {
                throw new ArgumentNullException("message");
            }

            #endregion

            MidiEvent newMidiEvent = new MidiEvent(this, position, message);

            if(head == null)
            {
                head = newMidiEvent;
                tail = newMidiEvent;
            }
            else if(position >= tail.AbsoluteTicks)
            {
                newMidiEvent.Previous = tail;
                tail.Next = newMidiEvent;
                tail = newMidiEvent;
                endOfTrackMidiEvent.SetAbsoluteTicks(Length);
                endOfTrackMidiEvent.Previous = tail;
            }
            else
            {
                MidiEvent current = head;

                while(current.AbsoluteTicks < position)
                {
                    current = current.Next;
                }

                newMidiEvent.Next = current;
                newMidiEvent.Previous = current.Previous;

                if(current.Previous != null)
                {
                    current.Previous.Next = newMidiEvent;
                }
                else
                {
                    head = newMidiEvent;
                }

                current.Previous = newMidiEvent;
            }

            count++;

            #region Invariant

            AssertValid();

            #endregion
        }
Beispiel #9
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;
                    }
                }
            }
        }
Beispiel #10
0
        public void Write(MidiEvent e)
        {
            switch(e.MidiMessage.MessageType)
            {
                case MessageType.Channel:
                case MessageType.SystemCommon:
                case MessageType.SystemRealtime:
                    Write(e.DeltaTicks, (ShortMessage)e.MidiMessage);
                    break;

                case MessageType.SystemExclusive:
                    Write(e.DeltaTicks, (SysExMessage)e.MidiMessage);
                    break;

                case MessageType.Meta:
                    Write(e.DeltaTicks, (MetaMessage)e.MidiMessage);
                    break;
            }
        }
 public virtual void SetMidiEvent(MidiEvent ev)
 {
     SetDownEvent(ev);
 }
 public GuitarMessage(GuitarMessageList owner, MidiEvent downEvent, MidiEvent upEvent, GuitarMessageType type)
     : this(new MidiEventPair(owner, downEvent, upEvent), type)
 {
 }
 public void SetUpEvent(MidiEvent ev)
 {
     _eventPair.Up = ev;
 }
 public void SetUpdatedEventPair(MidiEvent ev)
 {
     setEventPair(new MidiEventPair(Owner, ev));
 }
 public void SetDownEvent(MidiEvent ev)
 {
     _eventPair.Down = ev;
 }
Beispiel #16
0
        /// <summary>
        /// Clears all of the MidiEvents, with the exception of the end of track
        /// message, from the Track.
        /// </summary>
        public void Clear()
        {
            head = tail = null;

            count = 1;

            endOfTrackMidiEvent.SetAbsoluteTicks(Length);

            #region Invariant

            AssertValid();

            #endregion
        }
Beispiel #17
0
 public Track()
 {
     endOfTrackMidiEvent = new MidiEvent(this, Length, MetaMessage.EndOfTrackMessage);
 }
 public virtual void SetUpEvent(MidiEvent ev)
 {
     props.SetUpEvent(ev);
 }
Beispiel #19
0
        /// <summary>
        /// Inserts an IMidiMessage at the specified position in absolute ticks.
        /// </summary>
        /// <param name="position">
        /// The position in the Track in absolute ticks in which to insert the
        /// IMidiMessage.
        /// </param>
        /// <param name="message">
        /// The IMidiMessage to insert.
        /// </param>
        public MidiEvent Insert(int position, IMidiMessage message)
        {
            #region Require

            if (position < 0)
            {
                throw new ArgumentOutOfRangeException("position", position,
                                                      "IMidiMessage position out of range.");
            }
            else if (message == null)
            {
                throw new ArgumentNullException("message");
            }

            #endregion

            MidiEvent newMidiEvent = new MidiEvent(this, position, message);

            if (head == null)
            {
                head = newMidiEvent;
                tail = newMidiEvent;
            }
            else if (position >= tail.AbsoluteTicks)
            {
                newMidiEvent.Previous = tail;
                tail.Next             = newMidiEvent;
                tail = newMidiEvent;
                endOfTrackMidiEvent.SetAbsoluteTicks(Length);
                endOfTrackMidiEvent.Previous = tail;
            }
            else
            {
                MidiEvent current = head;

                while (current.AbsoluteTicks < position)
                {
                    current = current.Next;
                }

                newMidiEvent.Next     = current;
                newMidiEvent.Previous = current.Previous;

                if (current.Previous != null)
                {
                    current.Previous.Next = newMidiEvent;
                }
                else
                {
                    head = newMidiEvent;
                }

                current.Previous = newMidiEvent;
            }

            count++;

            #region Invariant

            AssertValid();

            #endregion

            return(newMidiEvent);
        }
 public GuitarTextEvent(GuitarMessageList list, MidiEvent ev)
     : base(list, ev, null, GuitarMessageType.GuitarTextEvent)
 {
     this.Text = ev.Text;
 }
Beispiel #21
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();
            }
        }
Beispiel #22
0
        public void Move(MidiEvent e, int newPosition)
        {
            #region Require

            if(e.Owner != this)
            {
                throw new ArgumentException("MidiEvent does not belong to this Track.");
            }
            else if(newPosition < 0)
            {
                throw new ArgumentOutOfRangeException("newPosition");
            }
            else if(e == endOfTrackMidiEvent)
            {
                throw new InvalidOperationException(
                    "Cannot move end of track message. Use the EndOfTrackOffset property instead.");
            }

            #endregion

            MidiEvent previous = e.Previous;
            MidiEvent next = e.Next;

            if(e.Previous != null && e.Previous.AbsoluteTicks > newPosition)
            {
                e.Previous.Next = e.Next;

                if(e.Next != null)
                {
                    e.Next.Previous = e.Previous;
                }

                while(previous != null && previous.AbsoluteTicks > newPosition)
                {
                    next = previous;
                    previous = previous.Previous;
                }
            }
            else if(e.Next != null && e.Next.AbsoluteTicks < newPosition)
            {
                e.Next.Previous = e.Previous;

                if(e.Previous != null)
                {
                    e.Previous.Next = e.Next;
                }

                while(next != null && next.AbsoluteTicks < newPosition)
                {
                    previous = next;
                    next = next.Next;
                }
            }

            if(previous != null)
            {
                previous.Next = e;
            }

            if(next != null)
            {
                next.Previous = e;
            }

            e.Previous = previous;
            e.Next = next;
            e.SetAbsoluteTicks(newPosition);

            if(newPosition < head.AbsoluteTicks)
            {
                head = e;
            }

            if(newPosition > tail.AbsoluteTicks)
            {
                tail = e;
            }

            endOfTrackMidiEvent.SetAbsoluteTicks(Length);
            endOfTrackMidiEvent.Previous = tail;

            #region Invariant

            AssertValid();

            #endregion
        }
Beispiel #23
0
        /// <summary>
        /// Clears all of the MidiEvents, with the exception of the end of track
        /// message, from the Track.
        /// </summary>
        public void Clear()
        {
            head = tail = null;

            count = 1;

            #region Invariant

            AssertValid();

            #endregion
        }
Beispiel #24
0
 public Track()
 {
     endOfTrackMidiEvent = new MidiEvent(this, Length, MetaMessage.EndOfTrackMessage);
 }
Beispiel #25
0
        /// <summary>
        /// Merges the specified Track with the current Track.
        /// </summary>
        /// <param name="trk">
        /// The Track to merge with.
        /// </param>
        public void Merge(Track trk)
        {
            #region Require

            if(trk == null)
            {
                throw new ArgumentNullException("trk");
            }

            #endregion

            #region Guard

            if(trk == this)
            {
                return;
            }
            else if(trk.Count == 1)
            {
                return;
            }

            #endregion

            #if(DEBUG)
            int oldCount = Count;
            #endif

            count += trk.Count - 1;

            MidiEvent a = head;
            MidiEvent b = trk.head;
            MidiEvent current = null;

            Debug.Assert(b != null);

            if(a != null && a.AbsoluteTicks <= b.AbsoluteTicks)
            {
                current = new MidiEvent(this, a.AbsoluteTicks, a.MidiMessage);
                a = a.Next;
            }
            else
            {
                current = new MidiEvent(this, b.AbsoluteTicks, b.MidiMessage);
                b = b.Next;
            }

            head = current;

            while(a != null && b != null)
            {
                while(a != null && a.AbsoluteTicks <= b.AbsoluteTicks)
                {
                    current.Next = new MidiEvent(this, a.AbsoluteTicks, a.MidiMessage);
                    current.Next.Previous = current;
                    current = current.Next;
                    a = a.Next;
                }

                if(a != null)
                {
                    while(b != null && b.AbsoluteTicks <= a.AbsoluteTicks)
                    {
                        current.Next = new MidiEvent(this, b.AbsoluteTicks, b.MidiMessage);
                        current.Next.Previous = current;
                        current = current.Next;
                        b = b.Next;
                    }
                }
            }

            while(a != null)
            {
                current.Next = new MidiEvent(this, a.AbsoluteTicks, a.MidiMessage);
                current.Next.Previous = current;
                current = current.Next;
                a = a.Next;
            }

            while(b != null)
            {
                current.Next = new MidiEvent(this, b.AbsoluteTicks, b.MidiMessage);
                current.Next.Previous = current;
                current = current.Next;
                b = b.Next;
            }

            tail = current;

            endOfTrackMidiEvent.SetAbsoluteTicks(Length);
            endOfTrackMidiEvent.Previous = tail;

            #region Ensure

            Debug.Assert(count == oldCount + trk.Count - 1);

            #endregion

            #region Invariant

            AssertValid();

            #endregion
        }
Beispiel #26
0
        /// <summary>
        /// Dispatches IMidiMessages to their corresponding sink.
        /// </summary>
        /// <param name="message">
        /// The IMidiMessage to dispatch.
        /// </param>
        public void Dispatch(MidiEvent evt, Track track)
        {
            #region Require

            var message = evt.MidiMessage;

            if (message == null)
            {
                throw new ArgumentNullException("message");
            }

            #endregion

            switch (message.MessageType)
            {
            case MessageType.Channel:
                OnChannelMessageDispatched(new ChannelMessageEventArgs((ChannelMessage)message, evt.AbsoluteTicks), track);
                break;

            case MessageType.SystemExclusive:
                OnSysExMessageDispatched(new SysExMessageEventArgs((SysExMessage)message, evt.AbsoluteTicks), track);
                break;

            case MessageType.Meta:
                OnMetaMessageDispatched(new MetaMessageEventArgs((MetaMessage)message, evt.AbsoluteTicks), track);
                break;

            case MessageType.SystemCommon:
                OnSysCommonMessageDispatched(new SysCommonMessageEventArgs((SysCommonMessage)message, evt.AbsoluteTicks), track);
                break;

            case MessageType.SystemRealtime:
                switch (((SysRealtimeMessage)message).SysRealtimeType)
                {
                case SysRealtimeType.ActiveSense:
                    OnSysRealtimeMessageDispatched(SysRealtimeMessageEventArgs.ActiveSense, track);
                    break;

                case SysRealtimeType.Clock:
                    OnSysRealtimeMessageDispatched(SysRealtimeMessageEventArgs.Clock, track);
                    break;

                case SysRealtimeType.Continue:
                    OnSysRealtimeMessageDispatched(SysRealtimeMessageEventArgs.Continue, track);
                    break;

                case SysRealtimeType.Reset:
                    OnSysRealtimeMessageDispatched(SysRealtimeMessageEventArgs.Reset, track);
                    break;

                case SysRealtimeType.Start:
                    OnSysRealtimeMessageDispatched(SysRealtimeMessageEventArgs.Start, track);
                    break;

                case SysRealtimeType.Stop:
                    OnSysRealtimeMessageDispatched(SysRealtimeMessageEventArgs.Stop, track);
                    break;

                case SysRealtimeType.Tick:
                    OnSysRealtimeMessageDispatched(SysRealtimeMessageEventArgs.Tick, track);
                    break;
                }

                break;
            }
        }
Beispiel #27
0
        /// <summary>
        /// Removes the MidiEvent at the specified index.
        /// </summary>
        /// <param name="index">
        /// The index into the Track at which to remove the MidiEvent.
        /// </param>
        public void RemoveAt(int index)
        {
            #region Require

            if(index < 0)
            {
                throw new ArgumentOutOfRangeException("index", index, "Track index out of range.");
            }
            else if(index == Count - 1)
            {
                throw new ArgumentException("Cannot remove the end of track event.", "index");
            }

            #endregion

            MidiEvent current = GetMidiEvent(index);

            if(current.Previous != null)
            {
                current.Previous.Next = current.Next;
            }
            else
            {
                Debug.Assert(current == head);

                head = head.Next;
            }

            if(current.Next != null)
            {
                current.Next.Previous = current.Previous;
            }
            else
            {
                Debug.Assert(current == tail);

                tail = tail.Previous;

                endOfTrackMidiEvent.SetAbsoluteTicks(Length);
                endOfTrackMidiEvent.Previous = tail;
            }

            current.Next = current.Previous = null;

            count--;

            #region Invariant

            AssertValid();

            #endregion
        }
Beispiel #28
0
        /// <summary>
        /// Creates a notechart from the specified midi path and the actual charttype
        /// (i.e. ExpertSingle from notes.mid).  Due to the overhead necessary to
        /// parse a midi file.  I am going to cram all midi->chart operations into
        /// one function call.
        /// This function uses the Sanford midi parser.  While it is horribly slow
        /// on larger (e.g. RB) midis, it works without a hitch on every midi I've
        /// come across.
        /// </summary>
        /// <param name="chartSelection">
        /// The information on which particular notechart to use.
        /// </param>
        /// <param name="chartInfo">The metadata on the chart.</param>
        /// <param name="BPMChanges">The list of BPM changes for this chart.</param>
        /// <returns>
        /// A filled out Notechart containing the needed information from the *.mid file.
        /// </returns>
        public static Notes ParseMidiInformationSanford(ChartSelection chartSelection,
                                                        Info chartInfo,
                                                        List <BPMChange> BPMChanges)
        {
            Notes notechartToReturn = new Notes();

            notechartToReturn.instrument = chartSelection.instrument;
            notechartToReturn.difficulty = chartSelection.difficulty;

            // The following two switch's are used to get the proper midi terminology for
            // the selected track and difficulty.
            string instrumentPart = null;
            int    greenKey       = 0;
            int    redKey         = 0;
            int    yellowKey      = 0;
            int    blueKey        = 0;
            int    orangeKey      = 0;

            switch (chartSelection.instrument)
            {
            case "Single":
                instrumentPart = "PART GUITAR";
                break;

            case "DoubleGuitar":
                instrumentPart = "PART GUITAR COOP";
                break;

            case "DoubleBass":
                instrumentPart = "PART BASS";
                break;

            case "Drums":
                instrumentPart = "PART DRUMS";
                break;

            default:
                instrumentPart = "PART GUITAR";
                break;
            }

            switch (chartSelection.difficulty)
            {
            case "Expert":
                greenKey  = 96;
                redKey    = 97;
                yellowKey = 98;
                blueKey   = 99;
                orangeKey = 100;
                break;

            case "Hard":
                greenKey  = 84;
                redKey    = 85;
                yellowKey = 86;
                blueKey   = 87;
                orangeKey = 88;
                break;

            case "Medium":
                greenKey  = 72;
                redKey    = 73;
                yellowKey = 74;
                blueKey   = 75;
                orangeKey = 76;
                break;

            case "Easy":
                greenKey  = 60;
                redKey    = 61;
                yellowKey = 62;
                blueKey   = 63;
                orangeKey = 64;
                break;

            default:
                greenKey  = 96;
                redKey    = 97;
                yellowKey = 98;
                blueKey   = 99;
                orangeKey = 100;
                break;
            }

            Sequence mySequence = new Sequence(chartSelection.directory + "\\notes.mid");
            Track    trackToUse = new Track();

            chartInfo.resolution = mySequence.Division;

            // Go through each event in the first track (which contains the BPM changes)
            // and parse the resulting string.
            Track sanTrack = mySequence[0];

            foreach (Sanford.Multimedia.Midi.MidiEvent currEvent in sanTrack.Iterator())
            {
                if (currEvent.MidiMessage.MessageType == MessageType.Meta)
                {
                    MetaMessage currMessage = currEvent.MidiMessage as MetaMessage;
                    //currTickValue += Convert.ToUInt32(splitEventString[1]);
                    if (currMessage.MetaType == MetaType.Tempo)
                    {
                        TempoChangeBuilder tempoBuilder = new TempoChangeBuilder(currMessage);
                        int midiBPMChange = tempoBuilder.Tempo;
                        // In midi files, bpm chages are stored as "microseconds per quarter note"
                        // and must be converted to BPM, and then into the non decimal format the game
                        // uses.
                        double currBPMDouble = 60000000 / (double)midiBPMChange;
                        uint   BPMToAdd      = (uint)(currBPMDouble * 1000);
                        BPMChanges.Add(new BPMChange((uint)currEvent.AbsoluteTicks, (uint)BPMToAdd));
                    }
                }
            }

            // Find the specified instrument's track
            for (int i = 1; i < mySequence.Count; i++)
            {
                sanTrack = mySequence[i];
                Sanford.Multimedia.Midi.MidiEvent currEvent = sanTrack.GetMidiEvent(0);
                if (currEvent.MidiMessage.MessageType == MessageType.Meta)
                {
                    MetaMessage currMessage = currEvent.MidiMessage as MetaMessage;
                    if (currMessage.MetaType == MetaType.TrackName)
                    {
                        MetaTextBuilder trackName = new MetaTextBuilder(currMessage);

                        // -If we come across a "T1 GEMS" track, we're in GH1 territory.
                        // -GH2/FoF has both PART BASS and PART RHYTHM (one or the other depending
                        //  on the chart).
                        if ((trackName.Text == instrumentPart) || (trackName.Text == "T1 GEMS") ||
                            ((trackName.Text == "PART RHYTHM") && (instrumentPart == "PART BASS")))
                        {
                            trackToUse = sanTrack;
                        }
                    }
                }
            }

            Note currNote  = new Note();
            bool blankNote = true;

            // Scan through and record every note specific to the selected difficulty
            foreach (Sanford.Multimedia.Midi.MidiEvent currEvent in trackToUse.Iterator())
            {
                // We need to specify wether a note is blank or not so we don't add
                // blank notes from other difficulties into the chart, but if we have
                // a filled out note, any nonzero tick value means we are moving to a
                // new note, so we must cut our ties and add this note to the chart.
                if ((currEvent.DeltaTicks != 0) && !blankNote)
                {
                    notechartToReturn.notes.Add(currNote);
                    currNote  = new Note();
                    blankNote = true;
                }

                if (currEvent.MidiMessage.MessageType == MessageType.Channel)
                {
                    ChannelMessage currMessage = currEvent.MidiMessage as ChannelMessage;
                    if (currMessage.Command == ChannelCommand.NoteOn)
                    {
                        // Only consider notes within the octave our difficulty is in.
                        if (((currMessage.Data1 == greenKey) || (currMessage.Data1 == redKey) ||
                             (currMessage.Data1 == yellowKey) || (currMessage.Data1 == blueKey) ||
                             (currMessage.Data1 == orangeKey)) && (currMessage.Data2 != 0))
                        {
                            // If it's a new note, we need to setup the tick value of it.
                            if (blankNote)
                            {
                                //currNote.TickValue = totalTickValue;
                                currNote.tickValue = (uint)currEvent.AbsoluteTicks;
                                blankNote          = false;
                            }
                            if (currMessage.Data1 == greenKey)
                            {
                                currNote.addNote(0);
                            }
                            else if (currMessage.Data1 == redKey)
                            {
                                currNote.addNote(1);
                            }
                            else if (currMessage.Data1 == yellowKey)
                            {
                                currNote.addNote(2);
                            }
                            else if (currMessage.Data1 == blueKey)
                            {
                                currNote.addNote(3);
                            }
                            else if (currMessage.Data1 == orangeKey)
                            {
                                currNote.addNote(4);
                            }
                        }
                    }
                }
            }

            return(notechartToReturn);
        }
Beispiel #29
0
        /// <summary>
        /// Merges the specified Track with the current Track.
        /// </summary>
        /// <param name="trk">
        /// The Track to merge with.
        /// </param>
        public void Merge(Track trk)
        {
            #region Require

            if (trk == null)
            {
                throw new ArgumentNullException("trk");
            }

            #endregion

            #region Guard

            if (trk == this)
            {
                return;
            }
            else if (trk.Count == 1)
            {
                return;
            }

            #endregion

#if (DEBUG)
            int oldCount = Count;
#endif

            count += trk.Count - 1;

            MidiEvent a       = head;
            MidiEvent b       = trk.head;
            MidiEvent current = null;

            Debug.Assert(b != null);

            if (a != null && a.AbsoluteTicks <= b.AbsoluteTicks)
            {
                current = new MidiEvent(this, a.AbsoluteTicks, a.MidiMessage);
                a       = a.Next;
            }
            else
            {
                current = new MidiEvent(this, b.AbsoluteTicks, b.MidiMessage);
                b       = b.Next;
            }

            head = current;

            while (a != null && b != null)
            {
                while (a != null && a.AbsoluteTicks <= b.AbsoluteTicks)
                {
                    current.Next          = new MidiEvent(this, a.AbsoluteTicks, a.MidiMessage);
                    current.Next.Previous = current;
                    current = current.Next;
                    a       = a.Next;
                }

                if (a != null)
                {
                    while (b != null && b.AbsoluteTicks <= a.AbsoluteTicks)
                    {
                        current.Next          = new MidiEvent(this, b.AbsoluteTicks, b.MidiMessage);
                        current.Next.Previous = current;
                        current = current.Next;
                        b       = b.Next;
                    }
                }
            }

            while (a != null)
            {
                current.Next          = new MidiEvent(this, a.AbsoluteTicks, a.MidiMessage);
                current.Next.Previous = current;
                current = current.Next;
                a       = a.Next;
            }

            while (b != null)
            {
                current.Next          = new MidiEvent(this, b.AbsoluteTicks, b.MidiMessage);
                current.Next.Previous = current;
                current = current.Next;
                b       = b.Next;
            }

            tail = current;

            endOfTrackMidiEvent.SetAbsoluteTicks(Length);
            endOfTrackMidiEvent.Previous = tail;

            #region Ensure
#if (DEBUG)
            Debug.Assert(count == oldCount + trk.Count - 1);
#endif
            #endregion

            #region Invariant

            AssertValid();

            #endregion
        }
 public ChannelMessageBuilder Initialize(MidiEvent ev)
 {
     this.message = ev.MessageData;
     return this;
 }