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);
        }
Beispiel #2
0
        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);
        }
Beispiel #3
0
        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);
        }
        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);
                }
            }
        }
        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);
        }
Beispiel #6
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);
        }
        /// <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());
            }
        }