/// <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 { } }
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); }
/// <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); } }
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)); }