/// <summary> /// Sends system exclusive messages. /// </summary> /// <param name="message"> /// The system exclusive message to send. /// </param> public void Send(SysExMessage message) { // If the device is open. if (IsOpen()) { // Create header. MidiHeader header = new MidiHeader(); // System exclusive message data. string msg = message.Message; // // Initialize header. // header.data = Marshal.StringToHGlobalAnsi(msg); header.bufferLength = msg.Length; header.flags = 0; // Prepare header. ThrowOnError(midiOutPrepareHeader(handle, ref header, Marshal.SizeOf(header))); // Place header in queue to be retrieved later. syncHeaderQueue.Enqueue(header); // Send message. ThrowOnError(midiOutLongMsg(handle, ref header, Marshal.SizeOf(header))); } }
/// <summary> /// Visits system exclusive messages. /// </summary> /// <param name="message"> /// The SysExMessage to visit. /// </param> void Multimedia.Midi.IMidiMessageVisitor.Visit(SysExMessage message) { // System exclusive messages cancel running status. runningStatus = 0; // Send system exclusive message. MidiSender.Send(message); }
/// <summary> /// Handles triggering the system exclusive message received event. /// </summary> /// <param name="header"> /// Midi header containing the system exclusive message. /// </param> /// <param name="timeStamp"> /// Number of milliseconds that have passed since the input device /// began recording. /// </param> private void DispatchSysExMessage(MidiHeader header, int timeStamp) { // Create array for holding system exclusive data. byte[] data = new byte[header.bytesRecorded - 1]; // Get status byte. byte status = Marshal.ReadByte(header.data); // Copy system exclusive data into array (status byte is // excluded). for (int i = 1; i < header.bytesRecorded; i++) { data[i - 1] = Marshal.ReadByte(header.data, i); } // Create message. SysExMessage msg = new SysExMessage((SysExType)status, data); // Raise event. SysExReceived(this, new SysExEventArgs(msg, timeStamp)); }
/// <summary> /// Reads the data for the next track from the Midi file. /// </summary> /// <param name="trackNum"> /// The track number. /// </param> private void ReadNextTrack(int trackNum) { MetaType metaType = MetaType.TrackName; int status = 0; int runningStatus = 0; // Read length of track. binReader.ReadBytes(LengthByteCount); // Continue reading Midi events until the end of the track. while(metaType != MetaType.EndOfTrack) { // Next Midi message in track. IMidiMessage msg = null; // Ticks for next Midi event. int ticks = ReadVariableLengthQuantity(); // Read status byte for the next Midi message. status = binReader.ReadByte(); // If this is a status byte. if((status & StatusFlag) == StatusFlag) { // If the next Midi message is a channel message. if(ChannelMessage.IsChannelMessage(status)) { // Read channel message from the Midi file. msg = ReadChannelMessage(status); // Update running status. runningStatus = status; } // Else if the next Midi message is a meta message. else if(MetaMessage.IsMetaMessage(status)) { // Read the type of meta message. metaType = (MetaType)binReader.ReadByte(); // Read the length of the meta message data. int length = ReadVariableLengthQuantity(); // Read the meta message data. byte[] data = binReader.ReadBytes(length); // Create meta message. msg = new MetaMessage(metaType, data); } // Else if the next Midi message is a system exclusive // message. else if(SysExMessage.IsSysExMessage(status)) { // The type of system exclusive message. SysExType type = (SysExType)status; // Read the length of the system exclusive data. int length = ReadVariableLengthQuantity(); // Read the system exclusive data. byte[] data = binReader.ReadBytes(length); // Create system exclusive message. msg = new SysExMessage(type, data); } } // Assumes running status. else { // Create channel message. msg = ReadChannelMessage(runningStatus, status); } // Create the next Midi event and store it in the specified // track. MidiEvent e = new MidiEvent(msg, ticks); tracks[trackNum].Add(e); } }
/// <summary> /// Initializes a new instance of the SysExEventArgs class with the /// specified system exclusive message and the time stamp. /// </summary> /// <param name="message"> /// The system exclusive message for this event. /// </param> /// <param name="timeStamp"> /// The time in milliseconds since the input device began recording. /// </param> public SysExEventArgs(SysExMessage message, int timeStamp) { this.message = message; this.timeStamp = timeStamp; }
/// <summary> /// Initializes a new instance of the SysExMessage class with /// another instance of the SysExMessage class. /// </summary> /// <param name="message"> /// The SysExMessage instance to use for initialization. /// </param> public SysExMessage(SysExMessage message) { type = message.type; this.message = new StringBuilder(message.Message); }
/// <summary> /// Reads the data for the next track from the Midi file. /// </summary> /// <param name="trackNum"> /// The track number. /// </param> private void ReadNextTrack(int trackNum) { MetaType metaType = MetaType.TrackName; int status = 0; int runningStatus = 0; // Read length of track. binReader.ReadBytes(LengthByteCount); // Continue reading Midi events until the end of the track. while (metaType != MetaType.EndOfTrack) { // Next Midi message in track. IMidiMessage msg = null; // Ticks for next Midi event. int ticks = ReadVariableLengthQuantity(); // Read status byte for the next Midi message. status = binReader.ReadByte(); // If this is a status byte. if ((status & StatusFlag) == StatusFlag) { // If the next Midi message is a channel message. if (ChannelMessage.IsChannelMessage(status)) { // Read channel message from the Midi file. msg = ReadChannelMessage(status); // Update running status. runningStatus = status; } // Else if the next Midi message is a meta message. else if (MetaMessage.IsMetaMessage(status)) { // Read the type of meta message. metaType = (MetaType)binReader.ReadByte(); // Read the length of the meta message data. int length = ReadVariableLengthQuantity(); // Read the meta message data. byte[] data = binReader.ReadBytes(length); // Create meta message. msg = new MetaMessage(metaType, data); } // Else if the next Midi message is a system exclusive // message. else if (SysExMessage.IsSysExMessage(status)) { // The type of system exclusive message. SysExType type = (SysExType)status; // Read the length of the system exclusive data. int length = ReadVariableLengthQuantity(); // Read the system exclusive data. byte[] data = binReader.ReadBytes(length); // Create system exclusive message. msg = new SysExMessage(type, data); } } // Assumes running status. else { // Create channel message. msg = ReadChannelMessage(runningStatus, status); } // Create the next Midi event and store it in the specified // track. MidiEvent e = new MidiEvent(msg, ticks); tracks[trackNum].Add(e); } }
/// <summary> /// Handles triggering the system exclusive message received event. /// </summary> /// <param name="header"> /// Midi header containing the system exclusive message. /// </param> /// <param name="timeStamp"> /// Number of milliseconds that have passed since the input device /// began recording. /// </param> private void DispatchSysExMessage(MidiHeader header, int timeStamp) { // Create array for holding system exclusive data. byte[] data = new byte[header.bytesRecorded - 1]; // Get status byte. byte status = Marshal.ReadByte(header.data); // Copy system exclusive data into array (status byte is // excluded). for(int i = 1; i < header.bytesRecorded; i++) { data[i - 1] = Marshal.ReadByte(header.data, i); } // Create message. SysExMessage msg = new SysExMessage((SysExType)status, data); // Raise event. SysExReceived(this, new SysExEventArgs(msg, timeStamp)); }
/// <summary> /// Sends system exclusive messages. /// </summary> /// <param name="message"> /// The system exclusive message to send. /// </param> public void Send(SysExMessage message) { // If the device is open. if(IsOpen()) { // Create header. MidiHeader header = new MidiHeader(); // System exclusive message data. string msg = message.Message; // // Initialize header. // header.data = Marshal.StringToHGlobalAnsi(msg); header.bufferLength = msg.Length; header.flags = 0; // Prepare header. ThrowOnError(midiOutPrepareHeader(handle, ref header, Marshal.SizeOf(header))); // Place header in queue to be retrieved later. syncHeaderQueue.Enqueue(header); // Send message. ThrowOnError(midiOutLongMsg(handle, ref header, Marshal.SizeOf(header))); } }