private static void TestInsert()
        {
            Track track = new Track();
            int midiEventCount = 2000;
            int positionMax = 32000;
            int endOfTrackOffset = 1000;
            int length = 0;
            int position = 0;
            ChannelMessage message = new ChannelMessage(ChannelCommand.NoteOff, 0, 60, 0);
            Random r = new Random();

            for(int i = 0; i < midiEventCount; i++)
            {
                position = r.Next(positionMax);

                if(position > length)
                {
                    length = position;
                }

                track.Insert(position, message);
            }

            track.EndOfTrackOffset = endOfTrackOffset;

            length += track.EndOfTrackOffset;

            Debug.Assert(track.Count == midiEventCount + 1);
            Debug.Assert(track.Length == length);
        }
        private static void TestRemoveAt()
        {
            Track a = new Track();
            ChannelMessage message = new ChannelMessage(ChannelCommand.NoteOff, 0, 60, 0);

            a.Insert(0, message);
            a.Insert(10, message);
            a.Insert(20, message);
            a.Insert(30, message);
            a.Insert(40, message);

            int count = a.Count;

            a.RemoveAt(0);

            Debug.Assert(a.Count == count - 1);

            a.RemoveAt(a.Count - 2);

            Debug.Assert(a.Count == count - 2);
            Debug.Assert(a.GetMidiEvent(0).AbsoluteTicks == 10);
            Debug.Assert(a.GetMidiEvent(a.Count - 2).AbsoluteTicks == 30);

            a.RemoveAt(0);
            a.RemoveAt(0);
            a.RemoveAt(0);

            Debug.Assert(a.Count == 1);
        }
Example #3
0
		private static void TestGunshotTrack(Sequence sequence)
		{
			var track = new Track();

			track.Insert(0, new ChannelMessage(ChannelCommand.ProgramChange, 1, 127));
			track.Insert(0, new ChannelMessage(ChannelCommand.NoteOn, 1, 35, 127));
			track.Insert(100, new ChannelMessage(ChannelCommand.NoteOff, 1, 35, 0));

			track.Insert(101, new ChannelMessage(ChannelCommand.NoteOn, 1, 76, 127));
			track.Insert(200, new ChannelMessage(ChannelCommand.NoteOff, 1, 76, 0));
			sequence.Add(track);
		}
Example #4
0
 private static IMidiMessage Convert(Event e, Track track)
 {
     if (e is NoteEvent)
     {
         NoteEvent note = (NoteEvent)e;
         if (note.Type == NoteEvent.EventType.NoteOff)
         {
             ChannelMessageBuilder b = new ChannelMessageBuilder();
             b.MidiChannel = note.Channel;
             b.Command = ChannelCommand.NoteOff;
             b.Data1 = ChannelNoteToMidiPitch(note.Pitch);
             b.Data2 = ChannelVelocityToMidiVolume(note.Velocity);
             b.Build();
             return b.Result;
         }
         else
         {
             ChannelMessageBuilder b = new ChannelMessageBuilder();
             b.MidiChannel = note.Channel;
             b.Command = ChannelCommand.NoteOn;
             b.Data1 = ChannelNoteToMidiPitch(note.Pitch);
             b.Data2 = ChannelVelocityToMidiVolume(note.Velocity);
             b.Build();
             return b.Result;
         }
     }
     else if (e is TempoEvent)
     {
         TempoEvent tempoEvent = (TempoEvent)e;
         TempoChangeBuilder builder = new TempoChangeBuilder();
         // convert BPM to microseconds
         builder.Tempo = 60000000 / tempoEvent.TempoBpm;
         builder.Build();
         return builder.Result;
     }
     else if (e is TimeSignatureEvent)
     {
         TimeSignatureEvent timeSignatureEvent = (TimeSignatureEvent)e;
         TimeSignatureBuilder builder = new TimeSignatureBuilder();
         builder.Numerator = (byte)timeSignatureEvent.BeatsPerBar;
         builder.Denominator = (byte)timeSignatureEvent.BeatValue;
         builder.ClocksPerMetronomeClick = 24;
         builder.ThirtySecondNotesPerQuarterNote = 8;
         builder.Build();
         return builder.Result;
     }
     else
     {
         Debug.Fail("unknown event type " + e.GetType().Name);
         return null;
     }
 }
        public WebTabTrackProperties(Track track, TrackEditor editorPro)
        {
            this.Track = track;

            this.Scale = 1.0;
            this.Offset = 3.0;
            this.Import = true;

            Events = new CopyChordList(editorPro);
            editorPro.SetTrack(track, GuitarDifficulty.Expert);

            Events.AddRange(editorPro.Messages.Chords.ToList());
        }
        public PEMidiTrack(Track track)
        {
            InitializeComponent();

            if (!DesignMode)
            {
                DifficultyButtons.ForEach(x =>
                    {
                        x.Button.Click += delegate(object o, EventArgs e)
                            {
                                setDifficulty(x.Difficulty);
                            };
                        x.Button.MouseDown += delegate(object sender, MouseEventArgs e)
                        {
                            x.Button.Tag = e.Location;
                        };
                        x.Button.MouseUp += delegate(object sender, MouseEventArgs e)
                        {
                            x.Button.Tag = null;
                        };
                        x.Button.MouseMove += delegate(object sender, MouseEventArgs e)
                        {
                            if (e.Button == System.Windows.Forms.MouseButtons.Left &&
                                x.Button.Tag != null && ((Point)x.Button.Tag).Distance(e.Location) > 3)
                            {
                                x.Button.DoDragDrop(new PETrackDifficulty(this, x.Difficulty), DragDropEffects.All);
                                ItemDifficultyBeginDrag.IfObjectNotNull(bd => bd(this, x.Difficulty, null));
                            }

                        };

                        x.Button.AllowDrop = true;

                        x.Button.DragEnter += new DragEventHandler(Button_DragEnter);
                        x.Button.DragDrop += new DragEventHandler(Button_DragDrop);
                    });

                setDifficulty(GuitarDifficulty.Expert);
                Track = track;

                labelTrackName.AllowDrop = true;
                labelTrackName.DragEnter += new DragEventHandler(panelTrackName_DragEnter);
                labelTrackName.DragDrop += new DragEventHandler(panelTrackName_DragDrop);
                labelTrackName.DragOver += new DragEventHandler(panelTrackName_DragOver);

                labelTrackName.MouseMove += new MouseEventHandler(panelTrackName_MouseMove);
                labelTrackName.MouseUp += new MouseEventHandler(panelTrackName_MouseUp);
                labelTrackName.MouseDown += new MouseEventHandler(panelTrackName_MouseDown);
            }
        }
        private static void TestMerge()
        {
            Track a = new Track();
            Track b = new Track();

            a.Merge(b);

            Debug.Assert(a.Count == 1);

            ChannelMessage message = new ChannelMessage(ChannelCommand.NoteOff, 0, 60, 0);

            b.Insert(0, message);
            b.Insert(10, message);
            b.Insert(20, message);
            b.Insert(30, message);
            b.Insert(40, message);

            a.Merge(b);

            Debug.Assert(a.Count == 1 + b.Count - 1);

            a.Clear();

            Debug.Assert(a.Count == 1);

            a.Insert(0, message);
            a.Insert(10, message);
            a.Insert(20, message);
            a.Insert(30, message);
            a.Insert(40, message);

            int count = a.Count;

            a.Merge(b);

            Debug.Assert(a.Count == count + b.Count - 1);
            Debug.Assert(a.GetMidiEvent(0).DeltaTicks == 0);
            Debug.Assert(a.GetMidiEvent(1).DeltaTicks == 0);
            Debug.Assert(a.GetMidiEvent(2).DeltaTicks == 10);
            Debug.Assert(a.GetMidiEvent(3).DeltaTicks == 0);
            Debug.Assert(a.GetMidiEvent(4).DeltaTicks == 10);
            Debug.Assert(a.GetMidiEvent(5).DeltaTicks == 0);
            Debug.Assert(a.GetMidiEvent(6).DeltaTicks == 10);
            Debug.Assert(a.GetMidiEvent(7).DeltaTicks == 0);
            Debug.Assert(a.GetMidiEvent(8).DeltaTicks == 10);
            Debug.Assert(a.GetMidiEvent(9).DeltaTicks == 0);
        }
Example #8
0
        public static void Save(List<List<Event>> allEvents, string path)
        {
            Sequence sequence = new Sequence();

            Dictionary<int, Track> tracks = new Dictionary<int, Track>();

            for (int trackIndex = 0; trackIndex < allEvents.Count; trackIndex++)
            {
                Track track = new Track();
                sequence.Add(track);
                List<Event> trackEvents = allEvents[trackIndex];
                foreach (var midiEvent in trackEvents.Select(trackEvent => new { Tick = trackEvent.Tick, MidiMessage = Convert(trackEvent, track) }))
                {
                    track.Insert(midiEvent.Tick, midiEvent.MidiMessage);
                }
            }

            sequence.Save(path);
        }
Example #9
0
		private static void TestPianoTrack(Sequence sequence)
		{
			var track = new Track();

			track.Insert(0, new ChannelMessage(ChannelCommand.ProgramChange, 0, 0));
			track.Insert(0, new ChannelMessage(ChannelCommand.NoteOn, 0, 35, 127));
			track.Insert(100, new ChannelMessage(ChannelCommand.NoteOff, 0, 35, 0));

			track.Insert(101, new ChannelMessage(ChannelCommand.NoteOn, 0, 76, 127));
			track.Insert(200, new ChannelMessage(ChannelCommand.NoteOff, 0, 76, 0));

			for (int i = 0; i < 1000; i += 10)
			{
				track.Insert(i, new ChannelMessage(ChannelCommand.NoteOn, 0, 76, 127));
				track.Insert(i + 9, new ChannelMessage(ChannelCommand.NoteOff, 0, 76));
			}

			sequence.Add(track);
		}
Example #10
0
        static void ReadMidiTrack(MidiData midiData, Sanford.Multimedia.Midi.Track midiTrack, int sequencerDivision)
        {
            Dictionary <int, float> noteTimes      = new Dictionary <int, float>();
            Dictionary <int, float> noteVelocities = new Dictionary <int, float>();

            for (int i = 0; i < midiTrack.Count; ++i)
            {
                MidiEvent midiEvent = midiTrack.GetMidiEvent(i);
                if (midiEvent.MidiMessage.GetBytes().Length < 3)
                {
                    continue;
                }

                byte  midiType = (byte)(midiEvent.MidiMessage.GetBytes()[0] & 0xFF);
                byte  note     = (byte)(midiEvent.MidiMessage.GetBytes()[1] & 0xFF);
                byte  velocity = (byte)(midiEvent.MidiMessage.GetBytes()[2] & 0xFF);
                float time     = (4.0f * midiEvent.AbsoluteTicks) / sequencerDivision;

                if (midiType == (byte)ChannelCommand.NoteOff ||
                    (midiType == (byte)ChannelCommand.NoteOn) && velocity == 0)
                {
                    if (noteTimes.ContainsKey(note))
                    {
                        Note noteObject = new Note();
                        noteObject.note     = note;
                        noteObject.start    = noteTimes[note];
                        noteObject.end      = time;
                        noteObject.velocity = noteVelocities[note];
                        midiData.notes.Add(noteObject);

                        noteTimes.Remove(note);
                        noteVelocities.Remove(note);
                    }
                }
                else if (midiType == (byte)ChannelCommand.NoteOn)
                {
                    noteTimes[note]      = time;
                    noteVelocities[note] = Mathf.Min(1.0f, velocity / 127.0f);
                }
            }
        }
        public void Read(Stream strm)
        {
            newTrack = new Track(FileType.Unknown);

            stream = strm;
            FindTrack();

            int trackLength = GetTrackLength();
            trackData = new byte[trackLength];

            int result = strm.Read(trackData, 0, trackLength);

            if (result < 0)
            {
                throw new MidiFileException("End of MIDI file unexpectedly reached.");
            }

            ParseTrackData();

            track = newTrack;
        }
 public void RemoveTrack(Track t)
 {
     if (Sequence.Contains(t))
     {
         Sequence.Remove(t);
     }
     this.dirtyItems |= DirtyItem.All;
 }
        public IEnumerable<GuitarTimeSignature> GetTimeSigMessages(GuitarMessageList owner, Track tempoTrack)
        {
            var ret = new List<GuitarTimeSignature>();

            try
            {
                var timeSigs = GetTimeSignaturesFromTrack(owner, tempoTrack);

                int nextTick = 0;
                timeSigs.For((t, i) =>
                {
                    timeSigs.ElementAtOrDefault(i + 1).IfObjectNotNull(next =>
                    {
                        nextTick = next.AbsoluteTicks;
                    },
                    Else =>
                    {
                        nextTick = Sequence.GetLength();
                    });

                    t.SetUpTick(nextTick);
                });
                ret.AddRange(timeSigs.ToList());
            }
            catch { }
            return ret;
        }
        public void CreateChordNameEvents(GuitarDifficulty difficulty,
            int[] GuitarTuning, int[] BassTuning, Track ownerTrack)
        {
            var x108 = Generate108().Where(x => x.Chord != null).ToList();

            foreach (var item in x108)
            {
                if (item.Chord.Notes.Count() > 1)
                {
                    ChordNameMeta name = null;
                    if (ownerTrack.Name.IsBassTrackName())
                    {
                        name = item.Chord.GetTunedChordName(BassTuning);
                    }
                    else
                    {
                        name = item.Chord.GetTunedChordName(GuitarTuning);
                    }

                    int data1 = -1;
                    var useUserChordName = false;
                    var chordName = string.Empty;
                    var hideChordName = false;

                    item.Chord.RootNoteConfig.IfNotNull(x => useUserChordName = x.UseUserChordName);
                    item.Chord.RootNoteConfig.IfNotNull(x => chordName = x.UserChordName);
                    item.Chord.RootNoteConfig.IfNotNull(x => data1 = x.RootNoteData1);
                    item.Chord.RootNoteConfig.IfNotNull(x => hideChordName = x.HideNoteName);

                    if (difficulty == GuitarDifficulty.Expert)
                    {
                        if (hideChordName || (data1 == -1 && (name == null || (name != null && name.ToneName.ToToneNameData1() == ToneNameData1.NotSet))))
                        {
                            ownerTrack.Insert(item.Ticks.Down, new ChannelMessage(ChannelCommand.NoteOn, Utility.ChordNameHiddenData1, 100 + item.Fret));
                            ownerTrack.Insert(item.Ticks.Up, new ChannelMessage(ChannelCommand.NoteOff, Utility.ChordNameHiddenData1, 0));
                        }
                        else
                        {
                            if (data1 == -1)
                            {
                                data1 = name.ToneName.ToToneNameData1().ToInt();
                            }
                            ownerTrack.Insert(item.Ticks.Down, new ChannelMessage(ChannelCommand.NoteOn, data1, 100 + item.Fret));
                            ownerTrack.Insert(item.Ticks.Up, new ChannelMessage(ChannelCommand.NoteOff, data1, 0));
                        }
                    }

                    var chordNameText = Utility.CreateChordNameText(item.Chord.Difficulty, useUserChordName ? chordName : name.ToStringEx());

                    if (chordNameText.IsNotEmpty())
                    {
                        ownerTrack.Insert(item.Chord.AbsoluteTicks, new MetaMessage(MetaType.Text, chordNameText));
                    }
                }
            }
        }
 public void Close()
 {
     midiTrack = null;
     Messages = null;
 }
 public void AddTrack(Track t)
 {
     if (!Sequence.Contains(t))
     {
         this.Sequence.Add(t);
     }
     this.dirtyItems |= DirtyItem.All;
 }
Example #17
0
        public override void SaveAsMIDI(string fileName)
        {
            if (NumTracks == 0)
            {
                throw new InvalidDataException("Questa canzone non ha tracce.");
            }

            CalculateTicks();
            var midi = new Sequence(96)
            {
                Format = 1
            };
            var metaTrack = new Sanford.Multimedia.Midi.Track();

            midi.Add(metaTrack);

            for (int i = 0; i < NumTracks; i++)
            {
                var track = new Sanford.Multimedia.Midi.Track();
                midi.Add(track);

                FreeNoteCommand freeNote    = null;
                MidiEvent       freeNoteOff = null;

                for (int j = 0; j < Commands[i].Count; j++)
                {
                    var e = Commands[i][j];

                    // Extended note ended ended and wasn't renewed
                    if (freeNoteOff != null && freeNoteOff.AbsoluteTicks < e.AbsoluteTicks * 2)
                    {
                        freeNote    = null;
                        freeNoteOff = null;
                    }

                    if (e.Command is VolumeCommand vol)
                    {
                        track.Insert(e.AbsoluteTicks * 2, new ChannelMessage(ChannelCommand.Controller, i, (int)ControllerType.Volume, vol.Volume / 2));
                    }
                    else if (e.Command is VoiceCommand voice)
                    {
                        // TODO: Fork and remove restriction
                        track.Insert(e.AbsoluteTicks * 2, new ChannelMessage(ChannelCommand.ProgramChange, i, voice.Voice & 0x7F));
                    }
                    else if (e.Command is PanpotCommand pan)
                    {
                        track.Insert(e.AbsoluteTicks * 2, new ChannelMessage(ChannelCommand.Controller, i, (int)ControllerType.Pan, pan.Panpot / 2 + 0x40));
                    }
                    else if (e.Command is BendCommand bend)
                    {
                        track.Insert(e.AbsoluteTicks * 2, new ChannelMessage(ChannelCommand.PitchWheel, i, 0, bend.Bend / 2 + 0x40));
                    }
                    else if (e.Command is BendRangeCommand bendr)
                    {
                        track.Insert(e.AbsoluteTicks * 2, new ChannelMessage(ChannelCommand.Controller, i, 20, bendr.Range / 2));
                    }
                    else if (e.Command is MLSSNoteCommand note)
                    {
                        // Extended note is playing and it should be extended by this note
                        if (freeNote != null && freeNote.Note - 0x80 == note.Note)
                        {
                            // Move the note off command
                            track.Move(freeNoteOff, freeNoteOff.AbsoluteTicks + note.Duration * 2);
                        }
                        // Extended note is playing but this note is different OR there is no extended note playing
                        // Either way we play a new note and forget that one
                        else
                        {
                            track.Insert(e.AbsoluteTicks * 2, new ChannelMessage(ChannelCommand.NoteOn, i, note.Note, 0x7F));
                            track.Insert(e.AbsoluteTicks * 2 + note.Duration * 2, new ChannelMessage(ChannelCommand.NoteOff, i, note.Note));
                            freeNote    = null;
                            freeNoteOff = null;
                        }
                    }
                    else if (e.Command is FreeNoteCommand free)
                    {
                        // Extended note is playing and it should be extended
                        if (freeNote != null && freeNote.Note == free.Note)
                        {
                            // Move the note off command
                            track.Move(freeNoteOff, freeNoteOff.AbsoluteTicks + free.Duration * 2);
                        }
                        // Extended note is playing but this note is different OR there is no extended note playing
                        // Either way we play a new note and forget that one
                        else
                        {
                            track.Insert(e.AbsoluteTicks * 2, new ChannelMessage(ChannelCommand.NoteOn, i, free.Note - 0x80, 0x7F));
                            track.Insert(e.AbsoluteTicks * 2 + free.Duration * 2, new ChannelMessage(ChannelCommand.NoteOff, i, free.Note - 0x80));
                            freeNote    = free;
                            freeNoteOff = track.GetMidiEvent(track.Count - 2); // -1 would be the end of track event
                        }
                    }
                    else if (i == 0 && e.Command is TempoCommand tempo)
                    {
                        var change = new TempoChangeBuilder {
                            Tempo = (60000000 / tempo.Tempo)
                        };
                        change.Build();
                        metaTrack.Insert(e.AbsoluteTicks * 2, change.Result);
                    }
                    else if (i == 0 && e.Command is GoToCommand goTo)
                    {
                        int jumpCmd = Commands[i].FindIndex(c => c.GetOffset() == goTo.Offset);
                        metaTrack.Insert(Commands[i][jumpCmd].AbsoluteTicks * 2, new MetaMessage(MetaType.Marker, new byte[] { (byte)'[' }));
                        metaTrack.Insert(e.AbsoluteTicks * 2, new MetaMessage(MetaType.Marker, new byte[] { (byte)']' }));
                    }
                    else if (e.Command is FinishCommand fine)
                    {
                        // TODO: Fix ticks before end of track event
                        // Library automatically is updating track.EndOfTrackOffset for us
                        break;
                    }
                }
            }
            midi.Save(fileName);
        }
 IEnumerable<GuitarTimeSignature> GetTimeSignaturesFromTrack(GuitarMessageList owner, Track tempoTrack)
 {
     var ret = new List<GuitarTimeSignature>();
     if (tempoTrack != null && tempoTrack.TimeSig.Any())
     {
         ret.AddRange(tempoTrack.TimeSig.Select(t => new GuitarTimeSignature(owner, t)));
     }
     else
     {
         ret.Add(GuitarTimeSignature.GetDefaultTimeSignature(owner));
     }
     return ret;
 }
Example #19
0
		public TrackLog(Track track)
		{
			_track = track;
		}
Example #20
0
        /// <summary>
        /// 添加mid文件到dataGridView
        /// </summary>
        /// <param name="trakInfo"></param>
        /// <param name="gridView"></param>
        private void AddTrackInfo2GridView(Sanford.Multimedia.Midi.Track trakInfo, DataGridView gridView)
        {
            //DataGridViewTextBoxColumn boxColumn = new DataGridViewTextBoxColumn();

            DataGridViewTextBoxColumn ColumnEventIndex = new DataGridViewTextBoxColumn();

            ColumnEventIndex.HeaderText = "Event-Num";
            ColumnEventIndex.Name       = "ColumnEventIndex";
            ColumnEventIndex.ReadOnly   = true;
            //ColumnEventIndex.Width = 200;

            DataGridViewTextBoxColumn ColumnAbsTicks = new DataGridViewTextBoxColumn();

            ColumnAbsTicks.HeaderText = "Abs-Ticks";
            ColumnAbsTicks.Name       = "ColumnAbsTicks";
            ColumnAbsTicks.ReadOnly   = true;
            //ColumnAbsTicks.Width = 80;
            //
            // ColumnDeltaTicks
            //
            DataGridViewTextBoxColumn ColumnDeltaTicks = new DataGridViewTextBoxColumn();

            ColumnDeltaTicks.HeaderText = "Dlt Ticks";
            ColumnDeltaTicks.Name       = "ColumnDeltaTicks";
            ColumnDeltaTicks.ReadOnly   = true;
            //
            // ColumnMsgStatus
            //
            DataGridViewTextBoxColumn ColumnMsgStatus = new DataGridViewTextBoxColumn();

            ColumnMsgStatus.HeaderText = "MsgStatus";
            ColumnMsgStatus.Name       = "ColumnMsgStatus";
            ColumnMsgStatus.ReadOnly   = true;
            //
            // ColumnMsgType
            //
            DataGridViewTextBoxColumn ColumnMsgType = new DataGridViewTextBoxColumn();

            ColumnMsgType.HeaderText = "MsgType";
            ColumnMsgType.Name       = "ColumnMsgType";
            ColumnMsgType.ReadOnly   = true;
            //
            // ColumnMsgSubType
            //
            DataGridViewTextBoxColumn ColumnMsgSubType = new DataGridViewTextBoxColumn();

            ColumnMsgSubType.HeaderText = "SubType";
            ColumnMsgSubType.Name       = "ColumnMsgSubType";
            ColumnMsgSubType.ReadOnly   = true;
            //
            // ColumnMsgData1
            //
            DataGridViewTextBoxColumn ColumnMsgData1 = new DataGridViewTextBoxColumn();

            ColumnMsgData1.HeaderText = "MsgData1";
            ColumnMsgData1.Name       = "ColumnMsgData1";
            ColumnMsgData1.ReadOnly   = true;
            //
            // ColumnMsgData2
            //
            DataGridViewTextBoxColumn ColumnMsgData2 = new DataGridViewTextBoxColumn();

            ColumnMsgData2.HeaderText = "MsgData2";
            ColumnMsgData2.Name       = "ColumnMsgData2";
            ColumnMsgData2.ReadOnly   = true;
            //
            // ColumnMidiChannel
            //
            DataGridViewTextBoxColumn ColumnMidiChannel = new DataGridViewTextBoxColumn();

            ColumnMidiChannel.HeaderText = "MidiChannel";
            ColumnMidiChannel.Name       = "ColumnMidiChannel";
            ColumnMidiChannel.ReadOnly   = true;
            //
            // ColumnBytes
            //
            DataGridViewTextBoxColumn ColumnBytes = new DataGridViewTextBoxColumn();

            ColumnBytes.HeaderText = "Bytes";
            ColumnBytes.Name       = "ColumnBytes";
            ColumnBytes.ReadOnly   = true;

            gridView.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
            gridView.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
                ColumnEventIndex,
                ColumnAbsTicks,
                ColumnDeltaTicks,
                ColumnMsgStatus,
                ColumnMsgType,
                ColumnMsgSubType,
                ColumnMsgData1,
                ColumnMsgData2,
                ColumnMidiChannel,
                ColumnBytes
            });
            for (int i = 0; i < trakInfo.Count; i++)
            {
                MidiEvent me = trakInfo.GetMidiEvent(i);
                //listViewTrackInfo.Items.Add(string.Format("音轨{0},EventNo = {1} Msg type = {2} , status = {3}", i, j, me.MidiMessage.MessageType, me.MidiMessage.Status));
                ArrayList stuff = new ArrayList();
                stuff.Add(i);
                stuff.Add(me.AbsoluteTicks);
                stuff.Add(me.DeltaTicks);
                stuff.Add(me.MidiMessage.Status);
                stuff.Add(me.MidiMessage.MessageType);
                switch (me.MidiMessage.MessageType)
                {
                case MessageType.Channel:
                    ChannelMessage cm = (ChannelMessage)me.MidiMessage;
                    stuff.Add(cm.Command);
                    stuff.Add(cm.Data1);
                    stuff.Add(cm.Data2);
                    stuff.Add(cm.MidiChannel);
                    break;

                case MessageType.SystemExclusive:
                    SysExMessage sem = (SysExMessage)me.MidiMessage;
                    stuff.Add(sem.SysExType);

                    break;

                case MessageType.SystemCommon:
                    SysCommonMessage scm = (SysCommonMessage)me.MidiMessage;
                    stuff.Add(scm.SysCommonType);
                    stuff.Add(scm.Data1);
                    stuff.Add(scm.Data2);

                    break;

                case MessageType.SystemRealtime:
                    SysRealtimeMessage srm = (SysRealtimeMessage)me.MidiMessage;
                    stuff.Add(srm.SysRealtimeType);

                    break;

                case MessageType.Meta:
                    MetaMessage mm = (MetaMessage)me.MidiMessage;
                    stuff.Add(mm.MetaType);
                    //if (mm.MetaType == MetaType.TrackName)
                    //{
                    //    stuff.Add(""); //data1
                    //    stuff.Add(""); //data2
                    //    stuff.Add("");//MidiChannel
                    //    byte[] bytesTrkName = mm.GetBytes();
                    //    //UnicodeEncoding encoding = new UnicodeEncoding();
                    //    //string trackName = encoding.GetString(mm.GetBytes());
                    //    //stuff.Add(/*trackName*/mm.GetBytes());
                    //}
                    break;
                }

                //object[] stuff = { i, j, me.MidiMessage.MessageType,me.AbsoluteTicks };
                gridView.Rows.Add(stuff.ToArray());
            }
        }
Example #21
0
        public override void SaveAsMIDI(string fileName)
        {
            if (NumTracks == 0)
            {
                throw new InvalidDataException("Questa canzone non ha tracce.");
            }

            CalculateTicks();
            var midi = new Sequence(24)
            {
                Format = 1
            };
            var metaTrack = new Sanford.Multimedia.Midi.Track();

            midi.Add(metaTrack);

            for (int i = 0; i < NumTracks; i++)
            {
                var track = new Sanford.Multimedia.Midi.Track();
                midi.Add(track);

                int endOfPattern = 0, startOfPatternTicks = 0, endOfPatternTicks = 0, shift = 0;
                var playing = new List <M4ANoteCommand>();

                for (int j = 0; j < Commands[i].Count; j++)
                {
                    var e     = Commands[i][j];
                    int ticks = e.AbsoluteTicks + (endOfPatternTicks - startOfPatternTicks);

                    if (e.Command is KeyShiftCommand keysh)
                    {
                        shift = keysh.Shift;
                    }
                    else if (e.Command is M4ANoteCommand note)
                    {
                        int n = (note.Note + shift).Clamp(0, 0x7F);
                        track.Insert(ticks, new ChannelMessage(ChannelCommand.NoteOn, i, n, note.Velocity));
                        if (note.Duration != -1)
                        {
                            track.Insert(ticks + note.Duration, new ChannelMessage(ChannelCommand.NoteOff, i, n));
                        }
                        else
                        {
                            playing.Add(note);
                        }
                    }
                    else if (e.Command is EndOfTieCommand eot)
                    {
                        M4ANoteCommand nc = null;

                        if (eot.Note == -1)
                        {
                            nc = playing.LastOrDefault();
                        }
                        else
                        {
                            nc = playing.LastOrDefault(n => n.Note == eot.Note);
                        }

                        if (nc != null)
                        {
                            int no = (nc.Note + shift).Clamp(0, 0x7F);
                            track.Insert(ticks, new ChannelMessage(ChannelCommand.NoteOff, i, no));
                            playing.Remove(nc);
                        }
                    }
                    else if (e.Command is VoiceCommand voice)
                    {
                        // TODO: Fork and remove restriction
                        track.Insert(ticks, new ChannelMessage(ChannelCommand.ProgramChange, i, voice.Voice & 0x7F));
                    }
                    else if (e.Command is VolumeCommand vol)
                    {
                        track.Insert(ticks, new ChannelMessage(ChannelCommand.Controller, i, (int)ControllerType.Volume, vol.Volume));
                    }
                    else if (e.Command is PanpotCommand pan)
                    {
                        track.Insert(ticks, new ChannelMessage(ChannelCommand.Controller, i, (int)ControllerType.Pan, pan.Panpot + 0x40));
                    }
                    else if (e.Command is BendCommand bend)
                    {
                        track.Insert(ticks, new ChannelMessage(ChannelCommand.PitchWheel, i, 0, bend.Bend + 0x40));
                    }
                    else if (e.Command is BendRangeCommand bendr)
                    {
                        track.Insert(ticks, new ChannelMessage(ChannelCommand.Controller, i, 20, bendr.Range));
                    }
                    else if (e.Command is LFOSpeedCommand lfos)
                    {
                        track.Insert(ticks, new ChannelMessage(ChannelCommand.Controller, i, 21, lfos.Speed));
                    }
                    else if (e.Command is LFODelayCommand lfodl)
                    {
                        track.Insert(ticks, new ChannelMessage(ChannelCommand.Controller, i, 26, lfodl.Delay));
                    }
                    else if (e.Command is ModDepthCommand mod)
                    {
                        track.Insert(ticks, new ChannelMessage(ChannelCommand.Controller, i, (int)ControllerType.ModulationWheel, mod.Depth));
                    }
                    else if (e.Command is ModTypeCommand modt)
                    {
                        track.Insert(ticks, new ChannelMessage(ChannelCommand.Controller, i, 22, modt.Type));
                    }
                    else if (e.Command is TuneCommand tune)
                    {
                        track.Insert(ticks, new ChannelMessage(ChannelCommand.Controller, i, 24, tune.Tune));
                    }
                    else if (e.Command is TempoCommand tempo)
                    {
                        var change = new TempoChangeBuilder {
                            Tempo = (60000000 / tempo.Tempo)
                        };
                        change.Build();
                        metaTrack.Insert(ticks, change.Result);
                    }
                    else if (e.Command is CallCommand patt)
                    {
                        int callCmd = Commands[i].FindIndex(c => c.GetOffset() == patt.Offset);
                        endOfPattern      = j;
                        endOfPatternTicks = e.AbsoluteTicks;
                        j = callCmd - 1; // -1 for incoming ++
                        startOfPatternTicks = Commands[i][j + 1].AbsoluteTicks;
                    }
                    else if (e.Command is ReturnCommand)
                    {
                        if (endOfPattern != 0)
                        {
                            j            = endOfPattern;
                            endOfPattern = startOfPatternTicks = endOfPatternTicks = 0;
                        }
                    }
                    else if (i == 0 && e.Command is GoToCommand goTo)
                    {
                        int jumpCmd = Commands[i].FindIndex(c => c.GetOffset() == goTo.Offset);
                        metaTrack.Insert(Commands[i][jumpCmd].AbsoluteTicks, new MetaMessage(MetaType.Marker, new byte[] { (byte)'[' }));
                        metaTrack.Insert(ticks, new MetaMessage(MetaType.Marker, new byte[] { (byte)']' }));
                    }
                    else if (e.Command is FinishCommand fine)
                    {
                        // TODO: Fix ticks before end of track event
                        // Library automatically is updating track.EndOfTrackOffset for us
                        break;
                    }
                }
            }
            midi.Save(fileName);
        }
Example #22
0
            private void onLoad(object sender, EventArgs args)
            {
                List<Track> newTracks = new List<Track>();
                for (int i = 0; i < sequence1.Count; i++)
                {
                    Track t = new Track();
                    foreach (MidiEvent e in sequence1[i].Iterator())
                    {
                        bool discard = false;
                        if (e.MidiMessage.MessageType == MessageType.Channel)
                        {
                            ChannelMessage m = (e.MidiMessage as ChannelMessage);
                            if (m.Command == ChannelCommand.Controller && (m.Data1 == (int)ControllerType.Volume || m.Data1 == (int)ControllerType.VolumeFine))
                            {
                                discard = true;
                            }
                        }
                        if (!discard) t.Insert(e.AbsoluteTicks, e.MidiMessage);
                    }
                    sequence1.Remove(sequence1[i]);
                    /*if (i == 0)*/
                    newTracks.Add(t);
                }
                foreach (Track t in newTracks)
                    sequence1.Add(t);
                foreach (MidiEvent e in sequence1[0].Iterator())
                {
                    if (e.MidiMessage.MessageType == MessageType.Channel)
                    {
                        ChannelMessage m = (e.MidiMessage as ChannelMessage);
                        if (m.Command == ChannelCommand.NoteOn)
                        {
                            int a = e.AbsoluteTicks;
                        }
                    }
                }
                //for (int i=0; i<4; i++)
                //    Sequence[i].Insert(1, new ChannelMessage(ChannelCommand.Controller, i, (int)ControllerType.Volume, 0 ));


                // then we return to loader code
                if (loadComplete != null)
                    loadComplete();
            }
Example #23
0
        private IEnumerable <int> GetTickIterator(MidiToolkit.Track track, Vst.Plugin plugin, int startPosition)
        {
            IEnumerator <MidiToolkit.MidiEvent> enumerator = track.Iterator().GetEnumerator();

            bool hasNext;
            bool breakLoop = false;

            for (hasNext = enumerator.MoveNext();
                 hasNext && enumerator.Current.AbsoluteTicks < startPosition;
                 hasNext = enumerator.MoveNext())
            {
            }

            int ticks = startPosition;

            while (hasNext)
            {
                while (ticks < enumerator.Current.AbsoluteTicks)
                {
                    if (ticks >= _length)
                    {
                        breakLoop = true;
                        break;
                    }

                    yield return(ticks);

                    ticks++;
                }

                if (breakLoop)
                {
                    break;
                }

                yield return(ticks);

                while (hasNext && enumerator.Current.AbsoluteTicks == ticks)
                {
                    if (enumerator.Current.MidiMessage is MidiToolkit.ChannelMessage cm)
                    {
                        if (cm.Command == MidiToolkit.ChannelCommand.NoteOn)
                        {
                            _masterSequencer.SendNoteOn(plugin, (byte)cm.Data1, (byte)cm.Data2);
                            _pressedNotes[cm.Data1] = true;
                        }
                        else if (cm.Command == MidiToolkit.ChannelCommand.NoteOff)
                        {
                            _masterSequencer.SendNoteOff(plugin, (byte)cm.Data1);
                            _pressedNotes[cm.Data1] = false;
                        }
                    }

                    hasNext = enumerator.MoveNext();
                }

                ticks++;
            }

            for (byte i = 0; i < 128; i++)
            {
                if (_pressedNotes[i])
                {
                    _masterSequencer.SendNoteOff(plugin, i);
                }
            }

            _numOfPlayingScores--;
        }
Example #24
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;
        }
Example #25
0
        private Sequence GetSequenceFromWPFStaffs(List <MusicalSymbol> WPFStaffs, Models.Track track)
        {
            List <string> notesOrderWithCrosses = new List <string>()
            {
                "c", "cis", "d", "dis", "e", "f", "fis", "g", "gis", "a", "ais", "b"
            };
            int absoluteTicks = 0;

            Sequence sequence = new Sequence();

            Sanford.Multimedia.Midi.Track metaTrack = new Sanford.Multimedia.Midi.Track();
            sequence.Add(metaTrack);

            // Calculate tempo
            var bar = (Bar)track.GetStaffs().Last().Bars.Last();

            int speed = (60000000 / bar.BarContext.BeatsPerMinute);

            byte[] tempo = new byte[3];
            tempo[0] = (byte)((speed >> 16) & 0xff);
            tempo[1] = (byte)((speed >> 8) & 0xff);
            tempo[2] = (byte)(speed & 0xff);
            metaTrack.Insert(0 /* Insert at 0 ticks*/, new MetaMessage(MetaType.Tempo, tempo));

            Sanford.Multimedia.Midi.Track notesTrack = new Sanford.Multimedia.Midi.Track();
            sequence.Add(notesTrack);

            for (int i = 0; i < WPFStaffs.Count; i++)
            {
                var musicalSymbol = WPFStaffs[i];
                switch (musicalSymbol.Type)
                {
                case MusicalSymbolType.Note:
                    PSAMControlLibrary.Note note = musicalSymbol as PSAMControlLibrary.Note;

                    // Calculate duration
                    double absoluteLength = 1.0 / (double)note.Duration;
                    absoluteLength += (absoluteLength / 2.0) * note.NumberOfDots;

                    double relationToQuartNote  = bar.BarContext.BeatsInBar.Item2 / 4.0;
                    double percentageOfBeatNote = (1.0 / bar.BarContext.BeatsInBar.Item2) / absoluteLength;
                    double deltaTicks           = (sequence.Division / relationToQuartNote) / percentageOfBeatNote;

                    // Calculate height
                    int noteHeight = notesOrderWithCrosses.IndexOf(note.Step.ToLower()) + ((note.Octave + 1) * 12);
                    noteHeight += note.Alter;
                    notesTrack.Insert(absoluteTicks, new ChannelMessage(ChannelCommand.NoteOn, 1, noteHeight, 90));     // Data2 = volume

                    absoluteTicks += (int)deltaTicks;
                    notesTrack.Insert(absoluteTicks, new ChannelMessage(ChannelCommand.NoteOn, 1, noteHeight, 0));     // Data2 = volume

                    break;

                case MusicalSymbolType.TimeSignature:
                    byte[] timeSignature = new byte[4];
                    // timeSignature[0] = (byte)_beatsPerBar;
                    //timeSignature[1] = (byte)(Math.Log(_beatNote) / Math.Log(2));
                    metaTrack.Insert(absoluteTicks, new MetaMessage(MetaType.TimeSignature, timeSignature));
                    break;

                default:
                    break;
                }
            }

            notesTrack.Insert(absoluteTicks, MetaMessage.EndOfTrackMessage);
            metaTrack.Insert(absoluteTicks, MetaMessage.EndOfTrackMessage);
            return(sequence);
        }
        public GuitarTrack SetTrack(Track selectedTrack, GuitarDifficulty diff)
        {
            if (selectedTrack == null || midiTrack == null)
            {
                midiTrack = null;
                dirtyItems |= DirtyItem.Track;
            }
            if (selectedTrack != null)
            {
                if (midiTrack == selectedTrack && !midiTrack.Dirty && currentDifficulty == diff && dirtyItems == DirtyItem.None)
                {
                }
                else
                {
                    midiTrack = selectedTrack;
                    currentDifficulty = diff;

                    if (midiTrack == null || midiTrack.Sequence == null)
                    {
                        this.SequenceDivision = 480;
                    }
                    else
                    {
                        this.SequenceDivision = midiTrack.Sequence.Division;
                    }

                    RebuildEvents();

                    this.dirtyItems = DirtyItem.None;
                    selectedTrack.Dirty = false;
                }
            }
            return this;
        }
        IEnumerable<Data1ChannelEventList> checkForInvalidNotes(GuitarMessageList owner, Track track, IEnumerable<int> data1List)
        {
            var ret = new List<Data1ChannelEventList>();
            try
            {
                var notesOnData2Zero = track.ChanMessages.Where(x => x.Data2 == 0 && x.Command == ChannelCommand.NoteOn).ToList();
                if (notesOnData2Zero.Any())
                {
                    track.Remove(notesOnData2Zero);

                    foreach (var x in notesOnData2Zero)
                    {
                        track.Insert(x.AbsoluteTicks, new ChannelMessage(ChannelCommand.NoteOff, x.Data1, 0, x.Channel));
                    }
                }

                if (track.Name.IsGuitarTrackName6())
                {
                    var bassTrainers = track.Meta.Where(x => x.Text.IsTrainerBass()).ToList();
                    var guitarTrainers = track.Meta.Where(x => x.Text.IsTrainerGuitar()).ToList();

                    if (bassTrainers.Any())
                    {
                        bassTrainers.ForEach(x => track.Remove(x));
                    }
                }

                if (track.Name.IsBassTrackName6())
                {
                    var bassTrainers = track.Meta.Where(x => x.Text.IsTrainerBass()).ToList();

                    var guitarTrainers = track.Meta.Where(x => x.Text.IsTrainerGuitar()).ToList();
                    if (guitarTrainers.Any())
                    {
                        guitarTrainers.ForEach(x => track.Remove(x));
                    }
                }

                ret.AddRange(track.GetCleanMessageList(data1List, owner));

            }
            catch (Exception ex)
            {
                ex.Message.OutputDebug();
            }

            return ret;
        }
Example #28
0
        public override void SaveAsMIDI(string fileName)
        {
            if (NumTracks == 0)
            {
                throw new InvalidDataException("This song has no tracks.");
            }

            CalculateTicks();
            var midi = new Sequence(24)
            {
                Format = 1
            };
            var metaTrack = new Sanford.Multimedia.Midi.Track();

            midi.Add(metaTrack);

            for (int i = 0; i < NumTracks; i++)
            {
                var track = new Sanford.Multimedia.Midi.Track();
                midi.Add(track);

                int endOfPattern = 0, startOfPatternTicks = 0, endOfPatternTicks = 0, shift = 0;
                var playing = new List <M4ANoteCommand>();

                for (int j = 0; j < Commands[i].Count; j++)
                {
                    var e     = Commands[i][j];
                    int ticks = e.AbsoluteTicks + (endOfPatternTicks - startOfPatternTicks);

                    switch (e.Command)
                    {
                    case KeyShiftCommand keysh:
                        shift = keysh.Shift;
                        break;

                    case M4ANoteCommand note:
                        int n = (note.Note + shift).Clamp(0, 0x7F);
                        track.Insert(ticks, new ChannelMessage(ChannelCommand.NoteOn, i, n, note.Velocity));
                        if (note.Duration != -1)
                        {
                            track.Insert(ticks + note.Duration, new ChannelMessage(ChannelCommand.NoteOff, i, n));
                        }
                        else
                        {
                            playing.Add(note);
                        }
                        break;

                    case EndOfTieCommand eot:
                        M4ANoteCommand nc = null;

                        if (eot.Note == -1)
                        {
                            nc = playing.LastOrDefault();
                        }
                        else
                        {
                            nc = playing.LastOrDefault(no => no.Note == eot.Note);
                        }

                        if (nc != null)
                        {
                            n = (nc.Note + shift).Clamp(0, 0x7F);
                            track.Insert(ticks, new ChannelMessage(ChannelCommand.NoteOff, i, n));
                            playing.Remove(nc);
                        }
                        break;

                    case PriorityCommand prio:
                        track.Insert(ticks, new ChannelMessage(ChannelCommand.Controller, i, (int)ControllerType.VolumeFine, prio.Priority));
                        break;

                    case VoiceCommand voice:
                        track.Insert(ticks, new ChannelMessage(ChannelCommand.ProgramChange, i, voice.Voice));
                        break;

                    case VolumeCommand vol:
                        track.Insert(ticks, new ChannelMessage(ChannelCommand.Controller, i, (int)ControllerType.Volume, vol.Volume));
                        break;

                    case PanpotCommand pan:
                        track.Insert(ticks, new ChannelMessage(ChannelCommand.Controller, i, (int)ControllerType.Pan, pan.Panpot + 0x40));
                        break;

                    case BendCommand bend:
                        track.Insert(ticks, new ChannelMessage(ChannelCommand.PitchWheel, i, 0, bend.Bend + 0x40));
                        break;

                    case BendRangeCommand bendr:
                        track.Insert(ticks, new ChannelMessage(ChannelCommand.Controller, i, 20, bendr.Range));
                        break;

                    case LFOSpeedCommand lfos:
                        track.Insert(ticks, new ChannelMessage(ChannelCommand.Controller, i, 21, lfos.Speed));
                        break;

                    case LFODelayCommand lfodl:
                        track.Insert(ticks, new ChannelMessage(ChannelCommand.Controller, i, 26, lfodl.Delay));
                        break;

                    case ModDepthCommand mod:
                        track.Insert(ticks, new ChannelMessage(ChannelCommand.Controller, i, (int)ControllerType.ModulationWheel, mod.Depth));
                        break;

                    case ModTypeCommand modt:
                        track.Insert(ticks, new ChannelMessage(ChannelCommand.Controller, i, 22, modt.Type));
                        break;

                    case TuneCommand tune:
                        track.Insert(ticks, new ChannelMessage(ChannelCommand.Controller, i, 24, tune.Tune));
                        break;

                    case LibraryCommand xcmd:
                        track.Insert(ticks, new ChannelMessage(ChannelCommand.Controller, i, 30, xcmd.Command));
                        track.Insert(ticks, new ChannelMessage(ChannelCommand.Controller, i, 29, xcmd.Argument));
                        break;

                    case TempoCommand tempo:
                        var change = new TempoChangeBuilder {
                            Tempo = (60000000 / tempo.Tempo)
                        };
                        change.Build();
                        metaTrack.Insert(ticks, change.Result);
                        break;

                    case CallCommand patt:
                        int callCmd = Commands[i].FindIndex(c => c.GetOffset() == patt.Offset);
                        endOfPattern      = j;
                        endOfPatternTicks = e.AbsoluteTicks;
                        j = callCmd - 1;     // -1 for incoming ++
                        startOfPatternTicks = Commands[i][j + 1].AbsoluteTicks;
                        break;

                    case ReturnCommand _:
                        if (endOfPattern != 0)
                        {
                            j            = endOfPattern;
                            endOfPattern = startOfPatternTicks = endOfPatternTicks = 0;
                        }
                        break;

                    case GoToCommand goTo:
                        if (i == 0)
                        {
                            int jumpCmd = Commands[i].FindIndex(c => c.GetOffset() == goTo.Offset);
                            metaTrack.Insert(Commands[i][jumpCmd].AbsoluteTicks, new MetaMessage(MetaType.Marker, new byte[] { (byte)'[' }));
                            metaTrack.Insert(ticks, new MetaMessage(MetaType.Marker, new byte[] { (byte)']' }));
                        }
                        break;

                    case FinishCommand _:
                        goto endOfTrack;
                    }
                }

                endOfTrack :;
            }
            midi.Save(fileName);
        }
Example #29
0
    public static NotationTrack parseMidiTrack(Midi.Track track, int division, ref Regex fingerPattern)
    {
        int microsecondsPerBeat = Midi.PpqnClock.DefaultTempo;

        float time = 0;

        TrackStatus    trackStatus = new TrackStatus();
        FingerChordMap fingerMap   = new FingerChordMap();

        List <Note> notes = new List <Note>();

        Regex fingerMetaPattern = new Regex("fingering-marker-pattern:(.*)");

        string name = "";

        foreach (Midi.MidiEvent e in track.Iterator())
        {
            time += e.DeltaTicks * microsecondsPerBeat / (division * 1000);

            switch (e.MidiMessage.MessageType)
            {
            case Midi.MessageType.Meta:
                Midi.MetaMessage mm = e.MidiMessage as Midi.MetaMessage;
                switch (mm.MetaType)
                {
                case Midi.MetaType.Tempo:
                    Midi.TempoChangeBuilder builder = new Midi.TempoChangeBuilder(mm);
                    microsecondsPerBeat = builder.Tempo;

                    break;

                case Midi.MetaType.Text:
                {
                    string text  = Encoding.Default.GetString(mm.GetBytes());
                    var    match = fingerMetaPattern.Match(text);
                    if (match.Success)
                    {
                        fingerPattern = new Regex(match.Groups[1].ToString());
                        Debug.LogFormat("Finger Pattern found: {0}", fingerPattern.ToString());
                    }
                }

                break;

                case Midi.MetaType.Marker:
                    if (fingerPattern != null)
                    {
                        string text  = Encoding.Default.GetString(mm.GetBytes());
                        var    match = fingerPattern.Match(text);
                        if (match.Success)
                        {
                            //Debug.LogFormat("Finger: {0}", text);
                            try
                            {
                                int    pitch  = int.Parse(match.Groups[1].ToString());
                                Finger finger = (Finger)int.Parse(match.Groups[2].ToString());

                                if (!fingerMap.ContainsKey(e.AbsoluteTicks))
                                {
                                    fingerMap[e.AbsoluteTicks] = new FingerChord();
                                }

                                fingerMap[e.AbsoluteTicks][pitch] = finger;
                            }
                            catch (System.Exception except)
                            {
                                Debug.LogWarningFormat("fingering marker parse failed: {0}, {1}", text, except.Message);
                            }
                        }
                        //else
                        //	Debug.LogWarningFormat("fail marker: {0}", text);
                    }

                    break;

                case Midi.MetaType.TrackName:
                    name = Encoding.Default.GetString(mm.GetBytes());

                    break;
                }

                break;

            case Midi.MessageType.Channel:
                Midi.ChannelMessage cm = e.MidiMessage as Midi.ChannelMessage;

                if (!trackStatus.ContainsKey(cm.MidiChannel))
                {
                    trackStatus[cm.MidiChannel] = new ChannelStatus();
                }

                var commandType = cm.Command;
                if (commandType == Midi.ChannelCommand.NoteOn && cm.Data2 == 0)
                {
                    commandType = Midi.ChannelCommand.NoteOff;
                }

                switch (commandType)
                {
                case Midi.ChannelCommand.NoteOn:
                {
                    int pitch    = cm.Data1;
                    int velocity = cm.Data2;

                    if (pitch >= Piano.PitchMin && pitch <= Piano.PitchMax)
                    {
                        trackStatus[cm.MidiChannel][pitch] = new PitchStatus {
                            tick = e.AbsoluteTicks, startTime = time, velocity = velocity
                        }
                    }
                    ;
                }

                break;

                case Midi.ChannelCommand.NoteOff:
                {
                    int pitch = cm.Data1;

                    if (!trackStatus[cm.MidiChannel].ContainsKey(pitch))
                    {
                        Debug.LogWarningFormat("Unexpected noteOff: {0}, {1}", e.AbsoluteTicks, pitch);
                    }
                    else
                    {
                        PitchStatus status = trackStatus[cm.MidiChannel][pitch];

                        Note note = new Note {
                            tick = status.tick, start = status.startTime, duration = time - status.startTime, pitch = pitch, velocity = status.velocity
                        };

                        if (fingerMap.ContainsKey(note.tick) && fingerMap[note.tick].ContainsKey(note.pitch))
                        {
                            note.finger = fingerMap[note.tick][note.pitch];
                        }

                        notes.Add(note);
                    }
                }

                break;
                }

                break;
            }
        }

        NotationTrack notation = new NotationTrack();

        notation.notes = notes.ToArray();
        notation.name  = name;

        return(notation);
    }
 public void AddTrack(Track t)
 {
     if (IsLoaded)
         Sequence.Add(t);
 }
Example #31
0
 private void InitializeObjects()
 {
     isCreatingPitchBar = false;
     isClickingPitchBar = false;
     ChangeSize();
     LastPitchBar = null;
     SelectedPitchBar = null;
     hoveredPitchBar = null;
     pitchBarInCreation = null;
     PitchBars = new List<PitchBar>();
     sequence.Clear();
     SetMIDITempo();
     pitchBarTrack = new Track();
     sequence.Add(pitchBarTrack);
     if (PitchbarChanged != null)
         PitchbarChanged(this, PitchBars);
 }
Example #32
0
        internal void SaveAsMIDI(string fileName)
        {
            if (NumTracks == 0)
            {
                throw new InvalidDataException("This song has no tracks.");
            }
            if (ROM.Instance.Game.Engine.Type != EngineType.M4A)
            {
                throw new PlatformNotSupportedException("Exporting to MIDI from this game engine is not supported at this time.");
            }

            CalculateTicks();
            var midi = new Sequence(Engine.GetTicksPerBar() / 4)
            {
                Format = 2
            };

            for (int i = 0; i < NumTracks; i++)
            {
                var track = new Sanford.Multimedia.Midi.Track();
                midi.Add(track);

                int endOfPattern = 0, startOfPatternTicks = 0, endOfPatternTicks = 0, shift = 0;
                var playing = new List <M4ANoteCommand>();

                for (int j = 0; j < Commands[i].Count; j++)
                {
                    var e     = Commands[i][j];
                    int ticks = (int)(e.AbsoluteTicks + (endOfPatternTicks - startOfPatternTicks));

                    if (e.Command is KeyShiftCommand keysh)
                    {
                        shift = keysh.Shift;
                    }
                    else if (e.Command is M4ANoteCommand note)
                    {
                        int n = (note.Note + shift).Clamp(0, 127);
                        track.Insert(ticks, new ChannelMessage(ChannelCommand.NoteOn, i, n, note.Velocity));
                        if (note.Duration != -1)
                        {
                            track.Insert(ticks + note.Duration, new ChannelMessage(ChannelCommand.NoteOff, i, n));
                        }
                        else
                        {
                            playing.Add(note);
                        }
                    }
                    else if (e.Command is EndOfTieCommand eot)
                    {
                        M4ANoteCommand nc = null;

                        if (eot.Note == -1)
                        {
                            nc = playing.LastOrDefault();
                        }
                        else
                        {
                            nc = playing.LastOrDefault(n => n.Note == eot.Note);
                        }

                        if (nc != null)
                        {
                            int no = (nc.Note + shift).Clamp(0, 127);
                            track.Insert(ticks, new ChannelMessage(ChannelCommand.NoteOff, i, no));
                            playing.Remove(nc);
                        }
                    }
                    else if (e.Command is VoiceCommand voice)
                    {
                        track.Insert(ticks, new ChannelMessage(ChannelCommand.ProgramChange, i, voice.Voice));
                    }
                    else if (e.Command is VolumeCommand vol)
                    {
                        track.Insert(ticks, new ChannelMessage(ChannelCommand.Controller, i, (int)ControllerType.Volume, vol.Volume));
                    }
                    else if (e.Command is PanpotCommand pan)
                    {
                        track.Insert(ticks, new ChannelMessage(ChannelCommand.Controller, i, (int)ControllerType.Pan, pan.Panpot + 0x40));
                    }
                    else if (e.Command is BendCommand bend)
                    {
                        track.Insert(ticks, new ChannelMessage(ChannelCommand.PitchWheel, i, 0, bend.Bend + 0x40));
                    }
                    else if (e.Command is BendRangeCommand bendr)
                    {
                        track.Insert(ticks, new ChannelMessage(ChannelCommand.Controller, i, 20, bendr.Range));
                    }
                    else if (e.Command is LFOSpeedCommand lfos)
                    {
                        track.Insert(ticks, new ChannelMessage(ChannelCommand.Controller, i, 21, lfos.Speed));
                    }
                    else if (e.Command is LFODelayCommand lfodl)
                    {
                        track.Insert(ticks, new ChannelMessage(ChannelCommand.Controller, i, 26, lfodl.Delay));
                    }
                    else if (e.Command is ModDepthCommand mod)
                    {
                        track.Insert(ticks, new ChannelMessage(ChannelCommand.Controller, i, (int)ControllerType.ModulationWheel, mod.Depth));
                    }
                    else if (e.Command is ModTypeCommand modt)
                    {
                        track.Insert(ticks, new ChannelMessage(ChannelCommand.Controller, i, 22, modt.Type));
                    }
                    else if (e.Command is TuneCommand tune)
                    {
                        track.Insert(ticks, new ChannelMessage(ChannelCommand.Controller, i, 24, tune.Tune));
                    }
                    else if (e.Command is TempoCommand tempo)
                    {
                        var change = new TempoChangeBuilder {
                            Tempo = (60000000 / tempo.Tempo)
                        };
                        change.Build();
                        track.Insert(ticks, change.Result);
                    }
                    else if (e.Command is CallCommand patt)
                    {
                        int callCmd = Commands[i].FindIndex(c => c.Offset == patt.Offset);
                        endOfPattern      = j;
                        endOfPatternTicks = (int)e.AbsoluteTicks;
                        j = callCmd - 1; // -1 for incoming ++
                        startOfPatternTicks = (int)Commands[i][j + 1].AbsoluteTicks;
                    }
                    else if (e.Command is ReturnCommand)
                    {
                        if (endOfPattern != 0)
                        {
                            j            = endOfPattern;
                            endOfPattern = startOfPatternTicks = endOfPatternTicks = 0;
                        }
                    }
                    else if (i == 0 && e.Command is GoToCommand goTo)
                    {
                        track.Insert(ticks, new MetaMessage(MetaType.Marker, new byte[] { (byte)']' }));
                        int jumpCmd = Commands[i].FindIndex(c => c.Offset == goTo.Offset);
                        track.Insert((int)Commands[i][jumpCmd].AbsoluteTicks, new MetaMessage(MetaType.Marker, new byte[] { (byte)'[' }));
                    }
                    else if (e.Command is FinishCommand fine)
                    {
                        track.Insert(ticks, new MetaMessage(MetaType.EndOfTrack, new byte[0]));
                        break;
                    }
                }
            }
            midi.Save(fileName);
        }
Example #33
0
        public double outputToMidi(Song output)
        {
            //5 Tracks (Just in case; so far MIDIOut is currently utilizing 2: 1 for instrument and another for notes). Each track added to sequence right after
            Track[] track = new Track[5];
            double songLen = 0;
            for (int i = 0; i < 5; i++)
            {
                track[i] = new Track();
                sequence.Add(track[i]);
            }
            //Set the tempo (assuming Song.Tempo is in bpm)
            tempoBuilder.Tempo = (int)(1.0 / output.Tempo * 60000000);
            tempoBuilder.Build();
            track[0].Insert(0, tempoBuilder.Result);
            //Set instrument
            /*builder.Command = ChannelCommand.ProgramChange;
            //builder.Data1 = (int)GeneralMidiInstrument.AcousticGrandPiano;
            builder.Data2 = 0;
            builder.Build();
            track[1].Insert(0, builder.Result);*/
            //Tick position
            int pos = 0;
            //Note length
            int len = 0;
            //MidiChannel number
            int c = 1;
            //Set MidiChannel number to 1
            builder.MidiChannel = c;
            //Iterate through the chord voice and turn them on; Each iteration will save the note and length values
            int startOfSegment = 0;
            for (int i = 0; i < output.songData.Count; i++)
            {
                startOfSegment = pos;
                for (int j = 0; j < output.songData[i].chordPattern.Count; j++)
                {
                    //Reset channel values to stop outOfBoundsException : Austin
                    c = 1;
                    builder.MidiChannel = c;
                    foreach (var item in (output.songData[i].chordPattern[j].chordVoice))
                    {
                        String note = item.noteValue; //C, C#, D, D#, E, F, F#, G, G#, A, A#
                        len = item.length; //in 16th notes
                        //Switch note on
                        builder.Command = ChannelCommand.ProgramChange;
                        if (output.Genre == "Generic" || output.Genre == "Jazz")
                        {
                            builder.Data1 = (int)GeneralMidiInstrument.AcousticGrandPiano;
                        }
                        else if (output.Genre == "Classical")
                        {
                            builder.Data1 = (int)GeneralMidiInstrument.Violin;
                        }
                        else if (output.Genre == "4-Chord Pop/Rock")
                        {
                            builder.Data1 = (int)GeneralMidiInstrument.ElectricGuitarMuted;
                        }
                        builder.Data2 = 0;
                        builder.Build();
                        track[1].Insert(pos, builder.Result);
                        builder.Command = ChannelCommand.NoteOn;
                        builder.Data1 = midiValOfNote(note);
                        if (output.Genre == "Generic")
                        {
                            builder.Data2 = 100;
                        }
                        else if (output.Genre == "Classical")
                        {
                            builder.Data2 = 80;
                        }
                        else if (output.Genre == "Jazz")
                        {
                            builder.Data2 = 110;
                        }
                        else if (output.Genre == "4-Chord Pop/Rock")
                        {
                            builder.Data2 = 120;
                        }

                        builder.Build(); //Build the message
                        track[1].Insert(pos, builder.Result); //Insert into Track 1 at tick position 'pos'
                        //Increment MIDI channel by 1
                        c += 1;
                        builder.MidiChannel = c;

                    }//endforeach
                    /*Tick position increment; This will be based on the last note of the previous chord, but I think it's safe to assume that its length will be the same as the rest of the chord tones of that chord.
                     PpqnClock.PpqnMinValue is the minimum PPQ value (24) set by the class library PpqnClock.*/
                    songLen += len / 4;
                    pos += (PpqnClock.PpqnMinValue / 4 * len);
                    c = 1;
                    builder.MidiChannel = c;

                    foreach (var item in (output.songData[i].chordPattern[j].chordVoice))
                    {
                        String note = item.noteValue;
                        len = item.length;
                        //Set Note Off
                        builder.Command = ChannelCommand.NoteOff;
                        builder.Data1 = midiValOfNote(note);
                        builder.Data2 = 0; //Set volume to mute
                        builder.Build(); //Build the message
                        track[1].Insert(pos, builder.Result); //Insert into Track 1 at tick position 'pos'
                        //Increment MIDI channel by 1
                        c += 1;
                        builder.MidiChannel = c;
                        //songLen += item.length / 16;
                    }//endforeach

                }//endfor

                for (int q = 0; q < output.songData[i].melodies.Count(); q++)
                {
                    pos = startOfSegment;
                    for (int j = 0; j < output.songData[i].melodies[q].melodicLine.Count(); j++)
                    {
                        Song.Note outputNote = output.songData[i].melodies[q].melodicLine[j];
                        String note = outputNote.noteValue;
                        int noteLength = outputNote.length; //in 16th notes
                        //Switch note on
                        builder.Command = ChannelCommand.ProgramChange;
                        if (output.Genre == "Generic")
                        {
                            builder.Data1 = (int)GeneralMidiInstrument.ElectricGuitarJazz;
                        }
                        else if (output.Genre == "Classical")
                        {
                            builder.Data1 = (int)GeneralMidiInstrument.Violin;
                        }
                        else if (output.Genre == "Twelve-tone")
                        {
                            builder.Data1 = (int)GeneralMidiInstrument.AcousticGrandPiano;

                        }
                        else if (output.Genre == "Jazz")
                        {
                            builder.Data1 = (int)GeneralMidiInstrument.AltoSax;
                        }
                        else if (output.Genre == "4-Chord Pop/Rock" && q==0)
                        {
                            builder.Data1 = (int)GeneralMidiInstrument.ChoirAahs;
                        }
                        else if (output.Genre == "4-Chord Pop/Rock" && q==1)
                        {
                            builder.Data1 = (int)GeneralMidiInstrument.ElectricBassPick;
                        }
                        builder.Data2 = 0;
                        builder.Build();
                        track[q+2].Insert(pos, builder.Result);
                        builder.Command = ChannelCommand.NoteOn;
                        builder.Data1 = midiValOfNote(note);
                        builder.Data2 = 127; //Set volume to max
                        builder.Build(); //Build the message
                        track[q+2].Insert(pos, builder.Result); //Insert into Track 1 at tick position 'pos'
                        //Increment MIDI channel by 1
                        pos += (PpqnClock.PpqnMinValue / 4 * noteLength);
                        //Set Note Off
                        builder.Command = ChannelCommand.NoteOff;
                        builder.Data1 = midiValOfNote(note);
                        builder.Data2 = 0; //Set volume to mute
                        builder.Build(); //Build the message
                        track[q+2].Insert(pos, builder.Result);

                    }
                }
            }//endfor
            //Submits file to the C:\BlottoBeats Folder where it is stored until another song is generated
            /*if (!Directory.Exists(@"C:\BlottoBeats"))
            {
                Directory.CreateDirectory(@"C:\BlottoBeats");

            }*/
            if (File.Exists("temp.mid"))
            {
                File.Delete("temp.mid");

            }

            sequence.Save("temp.mid");

            return ((double)pos) / (PpqnClock.PpqnMinValue / 4) / 4 / output.Tempo * 60;

            //Code to play sequence in client. Currently not functioning
            //s.Sequence = sequence;
            //s.Start();
        }
 public static Track CopyTrack(Track track, string newName)
 {
     Track ret = null;
     if (track != null)
     {
         try
         {
             ret = new Track(track.FileType, newName);
             ret.Merge(track);
         }
         catch { ret = null; }
     }
     return ret;
 }
Example #35
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
        }
 IEnumerable<GuitarTempo> internalGetTempo(GuitarMessageList owner, Track tempoTrack)
 {
     var ret = new List<GuitarTempo>();
     if (tempoTrack != null && tempoTrack.Tempo.Any())
     {
         ret.AddRange(
             tempoTrack.Tempo.Select(x =>
                 new GuitarTempo(owner, x)));
     }
     else
     {
         ret.Add(GuitarTempo.GetTempo(this, Utility.DummyTempo));
     }
     return ret;
 }
Example #37
0
 public void AddToTrack(Track track, double secondToTickMultiplier)
 {
     int startAbsoluteTick = (int)((StartTime + Program.MIDIPlaybackOffset) / secondToTickMultiplier);
     int endAbsoluteTick = (int)((EndTime + Program.MIDIPlaybackOffset) / secondToTickMultiplier);
     ChannelMessage startMessage = new ChannelMessage(ChannelCommand.NoteOn, 0, NoteIndex - Program.MIDI_OFFSET, Program.MIDIPlayer.Volume);
     ChannelMessage endMessage = new ChannelMessage(ChannelCommand.NoteOff, 0, NoteIndex - Program.MIDI_OFFSET);
     try
     {
         track.Insert(startAbsoluteTick, startMessage);
         track.Insert(endAbsoluteTick, endMessage);
     }
     catch (Exception) { }
 }
        public void AddTempoTrack(Track t)
        {
            if (t == null || t.Name == null)
                return;

            try
            {
                if (!Sequence.Contains(t))
                {
                    Sequence.AddTempo(t);
                }
            }
            catch { }

            dirtyItems |= DirtyItem.All;
        }
Example #39
0
 private void SetMIDITempo()
 {
     Track setTempoTrack = new Track();
     setTempoTrack.Insert(0, new MetaMessage(MetaType.TimeSignature, TimeSignatureData));
     setTempoTrack.Insert(0, new MetaMessage(MetaType.Tempo, SetTempoData));
     sequence.Add(setTempoTrack);
 }
Example #40
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
        }