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; } }
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; } }
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 }
/// <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); }
public ChannelMessageBuilder Initialize(MidiEvent ev) { this.message = ev.MessageData; return(this); }
public SongUtilSearchResultItem(string trackName, MidiEvent ev) { this.Event = ev; this.TrackName = TrackName; }
/// <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 }
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; } } } }
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; }
/// <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 }
public Track() { endOfTrackMidiEvent = new MidiEvent(this, Length, MetaMessage.EndOfTrackMessage); }
public virtual void SetUpEvent(MidiEvent ev) { props.SetUpEvent(ev); }
/// <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; }
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(); } }
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 }
/// <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 }
/// <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 }
/// <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; } }
/// <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 }
/// <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); }
/// <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; }