/// <inheritdoc/>
        public void GetMemory()
        {
            this.SmfFileHandle = MidiUtil.GetMthd(MidiFileName);
            tempoChanges.Clear();
            midiTimeInfo.Division = this.smfFileHandle.Division;

            Parse(0);
        }
 static MidiReader()
 {
     try {
         SmfStringFormatter.cc      = MidiUtil.LoadEnumerationFile("ext/cc.map");
         SmfStringFormatter.patches = MidiUtil.LoadEnumerationFile("ext/inst.map");
         SmfStringFormatter.drums   = MidiUtil.LoadEnumerationFile("ext/dk.map");
     } catch {
     }
 }
Exemple #3
0
    private void cutMusic(int from, int to, MidiMusic music, string outputFilename)
    {
        FileStream stream = File.Create(outputFilename);
        SmfWriter  writer = new SmfWriter(stream);

        writer.WriteHeader(music.Format, (short)music.Tracks.Count, music.DeltaTimeSpec);
        IList <MidiTrack> tracks = music.Tracks;

        for (var i = 0; i < tracks.Count; i++)
        {
            var  track          = tracks[i];
            int  passedTime     = 0;
            var  newTrack       = new MidiTrack();
            bool isFirstMessage = true;

            for (var j = 0; j < track.Messages.Count; j++)
            {
                var message = track.Messages[j];
                passedTime += message.DeltaTime;

                if (passedTime < from && message.Event.EventType != MidiEvent.NoteOn && message.Event.EventType != MidiEvent.NoteOff)
                {
                    var convertedMsg = MidiUtil.convertTimeToZero(message);
                    newTrack.AddMessage(convertedMsg);
                }
                else if (passedTime >= from && passedTime < to)
                {
                    if (isFirstMessage)
                    {
                        int newDeltaTime = passedTime - from;
                        newTrack.AddMessage(new MidiMessage(newDeltaTime, message.Event));
                        isFirstMessage = false;
                    }
                    else
                    {
                        newTrack.AddMessage(message);
                    }
                }
                else if (passedTime >= to && message.Event.EventType == MidiEvent.Meta && message.Event.MetaType == MidiMetaType.EndOfTrack)
                {
                    MidiMessage convertedMsg = MidiUtil.convertTimeToZero(message);
                    newTrack.AddMessage(convertedMsg);
                }
            }

            track = newTrack;
            // Debug.Log("Track " + (i + 1) + " Passed time:" + passedTime);
            writer.WriteTrack(track);
        }

        stream.Close();
    }
        /// <summary>
        ///     Attempts to create an MssEvent representation of <paramref name="midiEvent"/>.
        /// </summary>
        /// <returns>The MssEvent representation of midiEvent or null of there is no valid conversion.</returns>
        protected static MssEvent ConvertVstMidiEventToMssEvent(VstMidiEvent midiEvent,
                                                                long sampleTimeAtStartOfProcessingCycle,
                                                                double sampleRate)
        {
            MssEvent mssEvent = new MssEvent();

            //Sets the sample time for mssEvent.
            mssEvent.sampleTime = sampleTimeAtStartOfProcessingCycle + midiEvent.DeltaFrames;

            MssMsgType msgType = MidiUtil.GetMssTypeFromMidiData(midiEvent.Data);

            mssEvent.mssMsg.Type = msgType;

            //If msgType is "Unsupported" then midiEvent cannot be represented as an MssEvent
            if (msgType == MssMsgType.Unsupported)
            {
                return(null);
            }

            //Sets mssEvent's Data1 (midi channel).
            //Adds one because channels in an MssMsg start at 1 but channels in a VstMidiEvent start at 0
            mssEvent.mssMsg.Data1 = (midiEvent.Data[0] & 0x0F) + 1;

            //Sets mssEvent's Data2 and Data3 (the midi message's data bytes).
            if (msgType == MssMsgType.PitchBend)
            {
                //The two data bytes for pitch bend are used to store one 14-bit number so this number is stored in
                //mssEvent.Data3 and mssEvent.Data2 is not used.
                mssEvent.mssMsg.Data2 = MssMsgUtil.UNUSED_MSS_MSG_DATA;

                //data1 contains the least significant 7 bits of the pitch bend value and data2 contains the most
                //significant 7 bits
                mssEvent.mssMsg.Data3 = (midiEvent.Data[2] << 7) + midiEvent.Data[1];
            }
            else if (msgType == MssMsgType.ChanAftertouch)
            {
                mssEvent.mssMsg.Data2 = MssMsgUtil.UNUSED_MSS_MSG_DATA;
                mssEvent.mssMsg.Data3 = midiEvent.Data[1];
            }
            else
            {
                mssEvent.mssMsg.Data2 = midiEvent.Data[1];
                mssEvent.mssMsg.Data3 = midiEvent.Data[2];
            }

            return(mssEvent);
        }
        /// <summary>
        ///     Attempts to create a VstMidiEvent representation of <paramref name="mssEvent"/>.
        /// </summary>
        /// <returns>The VstMidiEvent representation of mssEvent or null of there is no valid conversion.</returns>
        protected static VstMidiEvent ConvertMssEventToVstMidiEvent(MssEvent mssEvent,
                                                                    long sampleTimeAtStartOfProcessingCycle,
                                                                    double sampleRate)
        {
            Debug.Assert(mssEvent.sampleTime >= sampleTimeAtStartOfProcessingCycle);

            //Calculate delta frames
            int deltaFrames = (int)(mssEvent.sampleTime - sampleTimeAtStartOfProcessingCycle);

            byte[] midiData = new byte[3];

            //Get status half of first byte.
            byte statusByte;

            if (MidiUtil.GetStatusFromMssMsgType(mssEvent.mssMsg.Type, out statusByte) == false)
            {
                return(null);
            }

            //subtract 1 becasue channels are 0 based in midi but 1 based in mss
            byte channelByte = (byte)(mssEvent.mssMsg.Data1AsInt - 1);

            midiData[0] = (byte)(statusByte | channelByte);

            if (mssEvent.mssMsg.Type == MssMsgType.PitchBend)
            {
                //most significant bits
                int MsbVal = (mssEvent.mssMsg.Data3AsInt) >> 7;
                midiData[2] = (byte)MsbVal;
                midiData[1] = (byte)((mssEvent.mssMsg.Data3AsInt) - (MsbVal << 7));
            }
            else if (mssEvent.mssMsg.Type == MssMsgType.ChanAftertouch)
            {
                midiData[1] = (byte)mssEvent.mssMsg.Data3AsInt;
                midiData[2] = 0;
            }
            else
            {
                midiData[1] = (byte)mssEvent.mssMsg.Data2AsInt;
                midiData[2] = (byte)mssEvent.mssMsg.Data3AsInt;
            }
            VstMidiEvent midiEvent = new VstMidiEvent(deltaFrames, 0, 0, midiData, 0, 0);

            return(midiEvent);
        }
Exemple #6
0
        /// <summary>
        /// Cuts track by "from" and "to" in ticks
        /// </summary>
        /// <param name="track"></param>
        /// <param name="fromTick"></param>
        /// <param name="toTick"></param>
        /// <returns></returns>
        private MidiTrack cutTrackByTicks(MidiTrack track, int fromTick, int toTick)
        {
            int       passedTicks    = 0;
            MidiTrack resultTrack    = new MidiTrack();
            bool      isFirstMessage = true;

            foreach (MidiMessage msg in track.Messages)
            {
                passedTicks += msg.DeltaTime;

                // messages before 'from' or messages after 'to':
                // Keep each message that isn't playing a note but give it a delta time of zero.
                if (passedTicks < fromTick && msg.Event.EventType != MidiEvent.NoteOn && msg.Event.EventType != MidiEvent.NoteOff ||
                    passedTicks >= toTick && msg.Event.EventType == MidiEvent.Meta && msg.Event.MetaType == MidiMetaType.EndOfTrack)
                {
                    MidiMessage convertedMsg = MidiUtil.convertTimeToZero(msg);
                    resultTrack.AddMessage(convertedMsg);
                }
                // messages within 'from' and 'to':
                // Keep these, just make sure the first message has the right time offset.
                else if (passedTicks >= fromTick && passedTicks < toTick)
                {
                    if (isFirstMessage)
                    {
                        resultTrack.AddMessage(new MidiMessage(passedTicks - fromTick, msg.Event));
                        isFirstMessage = false;
                    }
                    else
                    {
                        resultTrack.AddMessage(msg);
                    }
                }
            }


            // MidiEvent endOfTrackEvent = new MidiEvent(MidiEvent.Meta, MidiMetaType.EndOfTrack, (byte) 0x00, new byte[0]);
            // resultTrack.AddMessage(new MidiMessage(0, endOfTrackEvent));

            printTrackMessages(resultTrack);

            return(resultTrack);
        }
        //*******************************Helpers*******************************


        //if testMssToMidi is true then this method tests ConvertMssEventToVstMidiEvent. Otherwise this method tests ConvertVstMidiEventToMssEvent
        protected void Test_MsgConversion(MssMsgType msgType, int midiChannel, int midiParam1, int midiParam2, bool testMssToMidi)
        {
            long sampleTimeAtStartOfCycle = 12345;
            int  deltaFrames = 789;

            MidiHandlerProtectedWrapper midiHandler = Factory_MidiHandler_Basic();

            MssEvent mssEvent = new MssEvent();

            if (msgType == MssMsgType.PitchBend)
            {
                mssEvent.mssMsg = new MssMsg(msgType, midiChannel, MssMsgUtil.UNUSED_MSS_MSG_DATA, (midiParam2 << 7) + midiParam1);
            }
            else
            {
                mssEvent.mssMsg = new MssMsg(msgType, midiChannel, midiParam1, midiParam2);
            }
            mssEvent.sampleTime = sampleTimeAtStartOfCycle + deltaFrames;

            byte[]       midiData  = MidiUtil.CreateMidiData(msgType, midiChannel, (byte)midiParam1, (byte)midiParam2);
            VstMidiEvent midiEvent = new VstMidiEvent(deltaFrames, 0, 0, midiData, 0, 0x00);

            if (testMssToMidi == true)
            {
                MssEvent convertedMssEvent = midiHandler.ConvertVstMidiEventToMssEventWrapper(
                    midiEvent, sampleTimeAtStartOfCycle, this.hostInfoOutputPort.SampleRate);
                Assert.AreEqual(mssEvent, convertedMssEvent);
            }
            else
            {
                VstMidiEvent ConvertedMidiEvent = midiHandler.ConvertMssEventToVstMidiEventWrapper(
                    mssEvent, sampleTimeAtStartOfCycle, this.hostInfoOutputPort.SampleRate);
                Assert.AreEqual(midiEvent.Data, ConvertedMidiEvent.Data);
                Assert.AreEqual(midiEvent.DeltaFrames, ConvertedMidiEvent.DeltaFrames);
            }
        }
Exemple #8
0
 public void GetMemory()
 {
     this.MidiMessage -= GotMidiEventE;
     this.FileHandle   = MidiUtil.GetMthd(MidiFileName);
     this.MidiMessage += GotMidiEventE;
 }
 protected byte[] CreateMidiDataWithDefaultValues(MssMsgType msgType)
 {
     return(MidiUtil.CreateMidiData(msgType, 1, 0x00, 0x00));
 }