Example #1
0
        public MidiNoteMessage(uint channel, EMidiCommand command, uint note, uint velocity)
            : base(command, channel)
        {
            switch (command)
            {
            case EMidiCommand.NoteOn:
                action = (velocity == 0) ? EMidiNoteAction.Off : EMidiNoteAction.On;
                break;

            case EMidiCommand.NoteOff:
                action = EMidiNoteAction.Off;
                break;

            case EMidiCommand.KeyAfterTouch:
                action = EMidiNoteAction.VelChange;
                break;
            }
            this.note     = note;
            this.velocity = velocity;
        }
Example #2
0
        private MidiMessage[] GetMessages()
        {
            if (messages == null)
            {
                var msgList = new List <MidiMessage>();

                for (int b = 0; b < data.Length; b++)
                {
                    MidiMessage result = null;

                    uint         rawCommand = data[b];
                    uint         channel    = (rawCommand & 0x0f) + 1;
                    EMidiCommand command    = (EMidiCommand)(rawCommand & 0xF0);

                    if (command != EMidiCommand.SystemMessageMask)
                    {
                        // Common message
                        switch (command)
                        {
                        case EMidiCommand.NoteOff:
                        case EMidiCommand.NoteOn:
                        case EMidiCommand.KeyAfterTouch:
                            result = new MidiNoteMessage(channel, command, data[++b], data[++b]);
                            break;

                        case EMidiCommand.ControlChange:
                            result = new MidiControlChangeMessage(channel, data[++b], data[++b]);
                            break;

                        case EMidiCommand.PatchChange:
                            result = new MidiPatchChangeMessage(channel, data[++b]);
                            break;

                        case EMidiCommand.ChannelAfterTouch:
                            result = new MidiChannelAfterTouchMessage(channel, data[++b]);
                            break;

                        case EMidiCommand.PitchWheelChange:
                            result = new MidiPitchChangeMessage(channel, data[++b] + ((uint)data[++b] << 7));
                            break;

                        default:
                            throw new InvalidOperationException("Unsupported message in sequence: " + command);
                        }
                    }
                    else if (rawCommand == (uint)EMidiCommand.SystemExclusive)
                    {
                        var sysexBody = new List <byte>();

                        sysexBody.Add((byte)EMidiCommand.SystemExclusive);
                        byte bodyByte = 0;

                        while ((bodyByte = data[++b]) != (uint)EMidiCommand.EndOfSystemExclusive)
                        {
                            sysexBody.Add(bodyByte);
                        }

                        sysexBody.Add((byte)EMidiCommand.EndOfSystemExclusive);

                        result = new MidiSysexMessage(sysexBody.ToArray());
                    }
                    else
                    {
                        // System message
                        throw new InvalidOperationException("Only sysex and common messages supported in sequence");
                    }

                    msgList.Add(result);
                }

                messages = msgList.ToArray();
            }

            return(messages);
        }
Example #3
0
 public MidiCommonMessage(EMidiCommand command, uint channel) :
     base(command, channel)
 {
 }
Example #4
0
        private int ParseBuffer(byte[] data, int offset, int length, out MidiMessage message)
        {
            message = null;
            int messageLength = 0;

            if (length == 0)
            {
                // Should not happen
                return(0);
            }

            uint         rawCommand = data[offset];
            uint         channel    = (rawCommand & 0x0f) + 1;
            EMidiCommand command    = (EMidiCommand)(rawCommand & 0xF0);

            if (command == EMidiCommand.SystemMessageMask)
            {
                // System message
                channel       = 0;
                command       = (EMidiCommand)rawCommand;
                messageLength = 1;

                switch (command)
                {
                case EMidiCommand.TimingClock:
                    message = new TimingClockMessage();
                    break;

                case EMidiCommand.StartSequence:
                    message = new StartSequenceMessage();
                    break;

                case EMidiCommand.ContinueSequence:
                    message = new ContinueSequenceMessage();
                    break;

                case EMidiCommand.StopSequence:
                    message = new StopSequenceMessage();
                    break;

                case EMidiCommand.ActiveSensing:
                    message = new ActiveSensingMessage();
                    break;

                case EMidiCommand.SystemExclusive:
                    messageLength = ParseSysex(data, offset, length, ref message);
                    break;
                }
            }
            else
            {
                uint p1 = (length >= 2) ? data[offset + 1] : 0u;
                uint p2 = (length >= 3) ? data[offset + 2] : 0u;

                // Common message
                switch (command)
                {
                case EMidiCommand.NoteOff:
                case EMidiCommand.NoteOn:
                case EMidiCommand.KeyAfterTouch:
                    message       = new MidiNoteMessage(channel, command, p1, p2);
                    messageLength = 3;
                    break;

                case EMidiCommand.ControlChange:
                    message       = new MidiControlChangeMessage(channel, p1, p2);
                    messageLength = 3;
                    break;

                case EMidiCommand.PatchChange:
                    message       = new MidiPatchChangeMessage(channel, p1);
                    messageLength = 2;
                    break;

                case EMidiCommand.ChannelAfterTouch:
                    message       = new MidiChannelAfterTouchMessage(channel, p1);
                    messageLength = 2;
                    break;

                case EMidiCommand.PitchWheelChange:
                    message       = new MidiPitchChangeMessage(channel, p1 + (p2 << 7));
                    messageLength = 3;
                    break;
                }

                // Indicate truncated message in reply
                if (length < messageLength)
                {
                    messageLength = -1;
                }
            }

            return(messageLength);
        }
Example #5
0
        // Parse a midi message from a midi input MIM_DATA message
        private static MidiMessage ParseShortMessage(uint message)
        {
            MidiMessage  result     = null;
            uint         rawCommand = message & 0xff;
            uint         channel    = (rawCommand & 0x0f) + 1;
            EMidiCommand command    = (EMidiCommand)(rawCommand & 0xF0);

            if (command == EMidiCommand.SystemMessageMask)
            {
                // System message
                channel = 0;
                command = (EMidiCommand)rawCommand;

                switch (command)
                {
                case EMidiCommand.TimingClock:
                    result = new TimingClockMessage();
                    break;

                case EMidiCommand.StartSequence:
                    result = new StartSequenceMessage();
                    break;

                case EMidiCommand.ContinueSequence:
                    result = new ContinueSequenceMessage();
                    break;

                case EMidiCommand.StopSequence:
                    result = new StopSequenceMessage();
                    break;

                case EMidiCommand.ActiveSensing:
                    result = new ActiveSensingMessage();
                    break;
                }
            }
            else
            {
                uint p1 = (message >> 8) & 0xff;
                uint p2 = (message >> 16) & 0xff;

                // Common message
                switch (command)
                {
                case EMidiCommand.NoteOff:
                case EMidiCommand.NoteOn:
                case EMidiCommand.KeyAfterTouch:
                    result = new MidiNoteMessage(channel, command, p1, p2);
                    break;

                case EMidiCommand.ControlChange:
                    result = new MidiControlChangeMessage(channel, p1, p2);
                    break;

                case EMidiCommand.PatchChange:
                    result = new MidiPatchChangeMessage(channel, p1);
                    break;

                case EMidiCommand.ChannelAfterTouch:
                    result = new MidiChannelAfterTouchMessage(channel, p1);
                    break;

                case EMidiCommand.PitchWheelChange:
                    result = new MidiPitchChangeMessage(channel, p1 + (p2 << 7));
                    break;
                }
            }

            return(result);
        }
Example #6
0
        // Parse a midi message from a midi file
        private static MidiMessage ParseMidiMessage(MidiFileFormatReader mffr, uint runningStatus)
        {
            MidiMessage result = null;
            uint        rawCommand;
            uint        p1            = 0;
            bool        alreadyReadP1 = false;

            // Read the command
            rawCommand = mffr.ReadUInt8();

            if ((rawCommand & 0x80) == 0x80)
            {
                // New running status
                runningStatus = rawCommand;
            }
            else
            {
                // What we just read is actually p1 of a common message
                alreadyReadP1 = true;
                p1            = rawCommand;
                rawCommand    = runningStatus;
            }

            // Get channel
            uint         channel = (rawCommand & 0x0f) + 1;
            EMidiCommand command = (EMidiCommand)(rawCommand & 0xF0);

            if (command == EMidiCommand.SystemMessageMask)
            {
                // System message
                channel = 0;
                command = (EMidiCommand)rawCommand;

                switch (command)
                {
                // System messages - Exclusive
                case EMidiCommand.SystemExclusive:
                {
                    // Determine length of body + end-of-exclusive
                    uint   length    = mffr.ReadVarLengthQuantity();
                    byte[] sysexBody = new byte[length + 1];

                    // Read body
                    sysexBody[0] = (byte)EMidiCommand.SystemExclusive;
                    for (uint b = 0; b < length; b++)
                    {
                        sysexBody[b + 1] = mffr.ReadUInt8();
                    }

                    // Verify end-of-exclusive
                    if (sysexBody[length] != (byte)EMidiCommand.EndOfSystemExclusive)
                    {
                        throw new FormatException("Sysex of length " + length + " ending with " + sysexBody[length] + " instead of F7");
                    }

                    result = new MidiSysexMessage(sysexBody);
                    break;
                }

                // System messages - Common
                case EMidiCommand.SongPosition:
                case EMidiCommand.SongSelect:
                case EMidiCommand.TuneRequest:

                // System messages - Real time
                case EMidiCommand.TimingClock:
                case EMidiCommand.StartSequence:
                case EMidiCommand.ContinueSequence:
                case EMidiCommand.StopSequence:
                case EMidiCommand.ActiveSensing:
                    throw new FormatException(string.Format("Found event type {0} - not supported!", command));

                // Meta event
                case EMidiCommand.MetaEvent:
                    result = ParseMidiMetaMessage(mffr);
                    break;
                }
            }
            else
            {
                if (!alreadyReadP1)
                {
                    p1 = mffr.ReadUInt8();
                }

                // Channel message
                switch (command)
                {
                case EMidiCommand.NoteOff:
                case EMidiCommand.NoteOn:
                case EMidiCommand.KeyAfterTouch:
                    result = new MidiNoteMessage(channel, command, p1, mffr.ReadUInt8());
                    break;

                case EMidiCommand.ControlChange:
                    result = new MidiControlChangeMessage(channel, p1, mffr.ReadUInt8());
                    break;

                case EMidiCommand.PatchChange:
                    result = new MidiPatchChangeMessage(channel, p1);
                    break;

                case EMidiCommand.ChannelAfterTouch:
                    result = new MidiChannelAfterTouchMessage(channel, p1);
                    break;

                case EMidiCommand.PitchWheelChange:
                    result = new MidiPitchChangeMessage(channel, p1 + ((uint)mffr.ReadUInt8() << 7));
                    break;
                }
            }

            result.RunningStatus = runningStatus;
            return(result);
        }
Example #7
0

        
Example #8
0

        
Example #9
0
 // Build a serializable midi message from an actual midi message
 protected SerMidiMessage(MidiMessage midiMessage)
 {
     this.command = midiMessage.Command;
     this.channel = midiMessage.Channel;
 }