public void SysexMessage_continuation_writes_correctly_to_file() { var message = new SysexMessage(new byte[] { 0x7d, 0x30, 0x20, 0x10, 0x7f }, continuation: true); message.Write(writer); stream.ToArray().Should().Equal(new byte[] { 0xf7, 0x05, 0x7d, 0x30, 0x20, 0x10, 0x7f }); }
private static void ParseSysexBody(ArraySegment <byte> body, out SysexMessage message) { message = new SysexMessage { SysexID = 0, Data = body }; }
public void SysexMessage_continued_writes_correctly_to_file() { var message = new SysexMessage(new byte[] { 0x7d, 0x30, 0x20, 0x10 }); // No EOX (F7) message.Write(writer); stream.ToArray().Should().Equal(new byte[] { 0xf0, 0x04, 0x7d, 0x30, 0x20, 0x10 }); }
public override void Close() { // Immediately send reset - the scheduler isn't running at this point: var message = new SysexMessage(GenerateSysex(resetAddress, Array.Empty <byte>())); TransmitImmediate(message); }
public static bool TryParseSysex(ArraySegment <byte> input, out SysexMessage message, out ArraySegment <byte> remainingInput) { message = default(SysexMessage); remainingInput = input; if (input.Array[input.Offset] != (byte)MidiStatusByte.Sysex) { return(false); } for (var i = 0; i < (input.Count - 1); i++) { var b = input.Array[input.Offset + i + 1]; if (b == (byte)MidiStatusByte.EndOfSysex) { ParseSysexBody(new ArraySegment <byte>( input.Array, input.Offset + 1, i ), out message); return(true); } } return(false); }
/// <summary> /// Create a Sysex event /// </summary> /// <param name="data">a String that represents the data for the event.</param> /// <param name="tick">the position of the event in the sequence</param> /// <returns>the created Midi Sysex event</returns> public static MidiEvent CreateSysexEvent(string data, long tick) { var bytes = MidiHelper.StringToByteArray(data, ","); if (bytes.Length == 0) { throw new InvalidProgramException(string.Format("Could not parse the passed sysex event {0}", data)); } var sysexMessage = new SysexMessage(); sysexMessage.SetMessage(bytes, bytes.Length); // use base method to set the whole sysex message in one go var ev = new MidiEvent(sysexMessage, tick); return(ev); }
public override void TransmitSysex(SysexMessage message, PartsCollection parts) { // TODO: This is a bit roundabout - driver calling back into parts // But eventually, all the Roland specific stuff should be handled by the driver, not parts or player... int index = 0; byte[] data = message.Data; byte manufacturerId = data[index++]; if (manufacturerId != Roland.sysexId) { logger.Warning("Unknown sysex manufacturer ID"); return; } // Length of data minus manufacturer ID and ending F7. int count = data.Length - 2; int channel = data[index++]; int setupNumber = channel; index += 2; // Skip model and command IDs int address = (data[index++] << 14) | (data[index++] << 7) | (data[index++]); int offset = address - ActiveSetupBaseAddress; switch (count) { case 8: if (offset < ActiveSetupSize && channel < 16) { parts.SetupParam(channel, offset, data[index++]); } return; case 9: if (offset < ActiveSetupSize && channel < 16) { parts.SetupParam(channel, offset, data[index++]); parts.SetupParam(channel, offset + 1, data[index++]); } return; case 253: if (offset == 0 && channel < 16) { var setup = data[index..^ 2];
public static IntPtr Build(SysexMessage message) { byte[] data; if (!message.Continuation) { int length = message.Data.Length + 1; data = new byte[length]; data[0] = 0xf0; Array.Copy(message.Data, 0, data, 1, message.Data.Length); } else { data = message.Data; } return(Build(data)); }
// MidiMessage Convert(MidiMessage message) { // if (message instanceof javax.sound.midi.ShortMessage) { // final javax.sound.midi.ShortMessage shortMessage = (javax.sound.midi.ShortMessage)message; // return new ShortMessage((byte)shortMessage.getCommand(), (byte)shortMessage.getData1(), // (byte)shortMessage.getData2()); // } else if (message instanceof javax.sound.midi.SysexMessage) { // final javax.sound.midi.SysexMessage sysexMessage = (javax.sound.midi.SysexMessage)message; // return new SysexMessage(sysexMessage.getMessage(), sysexMessage.getLength()); // } // throw new IllegalArgumentException("Message could not be converted"); // } private MidiMessage HandleSysexMessage(SysexMessage message) { return(new SysexMessageAdapter(message)); }
public override void TransmitSysex(SysexMessage message, PartsCollection parts) { // GM driver ignores all custom sysex }
public virtual void TransmitSysex(SysexMessage message, PartsCollection parts) { TransmitEvent(message); }
/// <summary> /// Get the MIDI Sequence found in this input stream. /// <see cref="gnu.sound.midi.spi.MidiFileReader#GetSequence(Stream)"/> /// </summary> public override Sequence GetSequence(Stream stream) { // Good midi spec: // http://www.somascape.org/midi/tech/mfile.html // http://www.ccarh.org/courses/253/handout/smf/ var din = new MidiDataInputStream(stream); var mff = (ExtendedMidiFileFormat)GetMidiFileFormat(din.BaseStream); var seq = new Sequence(mff.DivisionType, mff.Resolution, 0, mff.MidiFileType); int ntracks = mff.NumberOfTracks; while (ntracks-- > 0) { Track track = seq.CreateTrack(); int Mtrk = din.ReadInt32(); if (Mtrk != 0x4D54726B) // "MTrk" { throw new InvalidMidiDataException("Invalid MIDI track header."); } int length = din.ReadInt32(); int runningStatus = -1; int click = 0; // Set this to true when we've hit an End of Track meta event. bool done = false; // Read all events. while (!done) { MidiMessage mm; int deltaTime = din.ReadVariableLengthInt(); click += deltaTime; // in Java bytes are signed (-128, +127) // where in C# it's not (0, 255). int statusByte = din.ReadByte(); if (statusByte < (int)MidiHelper.MidiEventType.SystemExclusive) { ShortMessage shortMessage; switch (statusByte & 0xF0) { case (int)MidiHelper.MidiEventType.NoteOff: case (int)MidiHelper.MidiEventType.NoteOn: case (int)MidiHelper.MidiEventType.AfterTouchPoly: case (int)MidiHelper.MidiEventType.ControlChange: case (int)MidiHelper.MidiEventType.PitchBend: case (int)MidiHelper.MidiEventType.SongPosition: shortMessage = new ShortMessage(); shortMessage.SetMessage(statusByte, din.ReadByte(), din.ReadByte()); runningStatus = statusByte; break; case (int)MidiHelper.MidiEventType.ProgramChange: case (int)MidiHelper.MidiEventType.AfterTouchChannel: case (int)MidiHelper.MidiEventType.SongSelect: case (int)MidiHelper.MidiEventType.BusSelect: shortMessage = new ShortMessage(); shortMessage.SetMessage(statusByte, din.ReadByte(), 0); runningStatus = statusByte; break; case (int)MidiHelper.MidiEventType.TuneRequest: case (int)MidiHelper.MidiEventType.EndOfExclusive: case (int)MidiHelper.MidiEventType.Clock: case (int)MidiHelper.MidiEventType.Start: case (int)MidiHelper.MidiEventType.Continue: case (int)MidiHelper.MidiEventType.Stop: case (int)MidiHelper.MidiEventType.ActiveSensing: case (int)MidiHelper.MidiEventType.SystemReset: shortMessage = new ShortMessage(); shortMessage.SetMessage(statusByte, 0, 0); runningStatus = statusByte; break; default: if (runningStatus != -1) { switch (runningStatus & 0xF0) { case (int)MidiHelper.MidiEventType.NoteOff: case (int)MidiHelper.MidiEventType.NoteOn: case (int)MidiHelper.MidiEventType.AfterTouchPoly: case (int)MidiHelper.MidiEventType.ControlChange: case (int)MidiHelper.MidiEventType.PitchBend: case (int)MidiHelper.MidiEventType.SongPosition: shortMessage = new ShortMessage(); shortMessage.SetMessage(runningStatus, statusByte, din.ReadByte()); break; case (int)MidiHelper.MidiEventType.ProgramChange: case (int)MidiHelper.MidiEventType.AfterTouchChannel: case (int)MidiHelper.MidiEventType.SongSelect: case (int)MidiHelper.MidiEventType.BusSelect: shortMessage = new ShortMessage(); shortMessage.SetMessage(runningStatus, statusByte, 0); continue; case (int)MidiHelper.MidiEventType.TuneRequest: case (int)MidiHelper.MidiEventType.EndOfExclusive: case (int)MidiHelper.MidiEventType.Clock: case (int)MidiHelper.MidiEventType.Start: case (int)MidiHelper.MidiEventType.Continue: case (int)MidiHelper.MidiEventType.Stop: case (int)MidiHelper.MidiEventType.ActiveSensing: case (int)MidiHelper.MidiEventType.SystemReset: shortMessage = new ShortMessage(); shortMessage.SetMessage(runningStatus, 0, 0); continue; default: throw new InvalidMidiDataException("Invalid Short MIDI Event: " + statusByte); } } else { throw new InvalidMidiDataException("Invalid Short MIDI Event: " + statusByte); } break; } mm = shortMessage; } else if (statusByte == (int)MidiHelper.MidiEventType.SystemExclusive || statusByte == (int)MidiHelper.MidiEventType.EndOfExclusive) { // System Exclusive event int sysexLength = din.ReadVariableLengthInt(); var sysexData = din.ReadBytes(sysexLength); var sysexMessage = new SysexMessage(); sysexMessage.SetMessage(statusByte, sysexData, sysexLength); mm = sysexMessage; runningStatus = -1; } else if (statusByte == (int)MidiHelper.META) { // Meta Message byte metaType = din.ReadByte(); int metaLength = din.ReadVariableLengthInt(); var metaData = din.ReadBytes(metaLength); var metaMessage = new MetaMessage(); metaMessage.SetMessage(metaType, metaData, metaLength); mm = metaMessage; // End of Track if (metaType == (byte)MidiHelper.MetaEventType.EndOfTrack) { done = true; } runningStatus = -1; } else { throw new InvalidMidiDataException("Invalid status byte: " + statusByte); } track.Add(new MidiEvent(mm, click)); } } return(seq); }
public SysexMessageAdapter(SysexMessage message) : base(message.Data, message.Length) { }
private void TransmitSysex(int address, byte[] data) { var message = new SysexMessage(GenerateSysex(address, data)); TransmitEvent(message); }