예제 #1
0
        public void When_RawData()
        {
            var message = new MidiNoteOffMessage(12, 36, 17);
            var data    = message.RawData.ToArray();

            CollectionAssert.AreEqual(new byte[] { 140, 36, 17 }, data);
        }
        public override async void PlayElement(MusicalSymbol element)
        {
            var note = element as Note;

            if (note == null || currentMidiOutputDevice == null)
            {
                return;
            }

            var firstNoteInMeasure = element.Measure.Elements.IndexOf(note) == 0;

            var channelNumber       = GetChannelNumber(Score.Staves.IndexOf(note.Staff));
            var actualChannelNumber = (pitchesPlaying[channelNumber].Contains(note.MidiPitch)) ? channelNumber + 1 : channelNumber;

            if (!pitchesPlaying[channelNumber].Contains(note.MidiPitch))
            {
                pitchesPlaying[channelNumber].Add(note.MidiPitch);
            }
            var midiMessageToSend = new MidiNoteOnMessage((byte)actualChannelNumber, (byte)note.Pitch.MidiPitch, firstNoteInMeasure ? (byte)127 : (byte)100);

            currentMidiOutputDevice.SendMessage(midiMessageToSend);

#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
            Task.Delay(note.BaseDuration.ToTimeSpan(Tempo)).ContinueWith((t, o) =>
            {
                var midiOffMessage = new MidiNoteOffMessage((byte)actualChannelNumber, (byte)note.Pitch.MidiPitch, 127);
                currentMidiOutputDevice.SendMessage(midiOffMessage);
                if (pitchesPlaying[channelNumber].Contains(note.MidiPitch))
                {
                    pitchesPlaying[channelNumber].Remove(note.MidiPitch);
                }
            }, null);
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
        }
예제 #3
0
        private void MidiInPort_MessageReceived(MidiInPort sender, MidiMessageReceivedEventArgs args)
        {
            IMidiMessage receivedMidiMessage = args.Message;

            System.Diagnostics.Debug.WriteLine(receivedMidiMessage.Timestamp.ToString());

            if (receivedMidiMessage.Type == MidiMessageType.NoteOn)
            {
                byte channel     = ((MidiNoteOnMessage)receivedMidiMessage).Channel;
                byte note        = ((MidiNoteOnMessage)receivedMidiMessage).Note;
                byte velocity    = ((MidiNoteOnMessage)receivedMidiMessage).Velocity;
                int  octave      = note / 12;
                int  fundamental = note % 12;
                System.Diagnostics.Debug.WriteLine(channel);
                System.Diagnostics.Debug.WriteLine(note);
                System.Diagnostics.Debug.WriteLine(velocity);
                System.Diagnostics.Debug.WriteLine(octave);
                System.Diagnostics.Debug.WriteLine(fundamental);


                IMidiMessage message = new MidiNoteOnMessage(channel, note, velocity);
                midiOutPort.SendMessage(message);
            }
            else if (receivedMidiMessage.Type == MidiMessageType.NoteOff)
            {
                byte         channel  = ((MidiNoteOffMessage)receivedMidiMessage).Channel;
                byte         note     = ((MidiNoteOffMessage)receivedMidiMessage).Note;
                byte         velocity = ((MidiNoteOffMessage)receivedMidiMessage).Velocity;
                IMidiMessage message  = new MidiNoteOffMessage(channel, note, velocity);
                midiOutPort.SendMessage(message);
            }
        }
        protected override void ProcessRecord()
        {
            if (ValidateCommonParameters())
            {
                var message = new MidiNoteOffMessage(Channel, Note, Velocity);

                Port.RawPort.SendMessage(message);
            }
        }
        protected override void ProcessRecord()
        {
            if (ValidateCommonParameters())
            {
                var message = new MidiNoteOffMessage(Channel, Note, Velocity);

                Port.RawPort.SendMessage(message);
            }
        }
예제 #6
0
        private void K_KeyReleased(object sender, RoutedEventArgs e)
        {
            // Same as K_KeyTapped but with MidiNoteOffMessage
            int note = OctaveInt * 12 + (int)sender;

            if (note > -1 && note < 128)
            {
                MidiNoteOffMessage msgO = new MidiNoteOffMessage(0, (byte)note, 100);
                O_KeyReleased?.Invoke(msgO, null);
            }
        }
예제 #7
0
        private void timer_tick(object sender, object e)
        {
            //var i = new MessageDialog(text[index].ToString()).ShowAsync();

            if (index > 0)
            {
                int       b         = text[index - 1] - '0';
                Rectangle rec_after = (Rectangle)KeyboardGrid.Children.ElementAt(b - 1);
                if (b % 2 == 0)
                {
                    rec_after.Fill = new SolidColorBrush(Color.FromArgb(220, 0, 0, 0));
                }
                else
                {
                    rec_after.Fill = new SolidColorBrush(Color.FromArgb(220, 255, 255, 255));
                }
                byte         note1 = (byte)(60 + b + (octaveInterval * 12));
                IMidiMessage midiMessageToSend1 = new MidiNoteOffMessage(channel, note1, velocity);
                midiOutPort.SendMessage(midiMessageToSend1);
            }

            if (index == len)
            {
                timer.Stop();
                return;
            }

            int a = text[index] - '0';

            Rectangle rec_before = (Rectangle)KeyboardGrid.Children.ElementAt(a - 1);

            rec_before.Fill = new SolidColorBrush(Color.FromArgb(50, 250, 0, 0));
            byte         note = (byte)(60 + a + (octaveInterval * 12));
            IMidiMessage midiMessageToSend = new MidiNoteOnMessage(channel, note, velocity);

            midiOutPort.SendMessage(midiMessageToSend);

            index++;

            /*if (len <= index)
             * {
             *  timer.Stop();
             *  midiMessageToSend = new MidiNoteOffMessage(channel, note, velocity);
             *  midiOutPort.SendMessage(midiMessageToSend);
             * }*/
        }
예제 #8
0
            public void SendMessage(Event evt)
            {
                IMidiMessage msg;

                switch (evt)
                {
                case NoteOnEvent on:
                    msg = new MidiNoteOnMessage(evt.Channel, on.Note, on.Velocity);
                    break;

                case NoteOffEvent off:
                    msg = new MidiNoteOffMessage(evt.Channel, off.Note, off.Velocity);
                    break;

                case ControlEvent ctrl:
                    msg = new MidiControlChangeMessage(evt.Channel, ctrl.Controller, ctrl.ControlValue);
                    break;

                default:
                    throw new ArgumentException("unsupported message type");
                }
                intSynth.SendMessage(msg);
            }
예제 #9
0
        /// <summary>
        /// Create a new MIDI message based on the message type and parameter(s) values,
        /// and send it to the chosen output device
        /// </summary>
        /// <param name="sender">Element that fired the event</param>
        /// <param name="e">Event arguments</param>
        private void sendButton_Click(object sender, Windows.UI.Xaml.RoutedEventArgs e)
        {
            IMidiMessage midiMessageToSend = null;

            switch (_currentMessageType)
            {
            case MidiMessageType.NoteOff:
                midiMessageToSend = new MidiNoteOffMessage(Convert.ToByte(GetParameterValue(parameter1)), Convert.ToByte(GetParameterValue(parameter2)), Convert.ToByte(GetParameterValue(parameter3)));
                break;

            case MidiMessageType.NoteOn:
                midiMessageToSend = new MidiNoteOnMessage(Convert.ToByte(GetParameterValue(parameter1)), Convert.ToByte(GetParameterValue(parameter2)), Convert.ToByte(GetParameterValue(parameter3)));
                break;

            case MidiMessageType.PolyphonicKeyPressure:
                midiMessageToSend = new MidiPolyphonicKeyPressureMessage(Convert.ToByte(GetParameterValue(parameter1)), Convert.ToByte(GetParameterValue(parameter2)), Convert.ToByte(GetParameterValue(parameter3)));
                break;

            case MidiMessageType.ControlChange:
                midiMessageToSend = new MidiControlChangeMessage(Convert.ToByte(GetParameterValue(parameter1)), Convert.ToByte(GetParameterValue(parameter2)), Convert.ToByte(GetParameterValue(parameter3)));
                break;

            case MidiMessageType.ProgramChange:
                midiMessageToSend = new MidiProgramChangeMessage(Convert.ToByte(GetParameterValue(parameter1)), Convert.ToByte(GetParameterValue(parameter2)));
                break;

            case MidiMessageType.ChannelPressure:
                midiMessageToSend = new MidiChannelPressureMessage(Convert.ToByte(GetParameterValue(parameter1)), Convert.ToByte(GetParameterValue(parameter2)));
                break;

            case MidiMessageType.PitchBendChange:
                midiMessageToSend = new MidiPitchBendChangeMessage(Convert.ToByte(GetParameterValue(parameter1)), Convert.ToUInt16(GetParameterValue(parameter2)));
                break;

            case MidiMessageType.SystemExclusive:
                var dataWriter         = new DataWriter();
                var sysExMessage       = sysExMessageContent.Text;
                var sysExMessageLength = sysExMessage.Length;

                // Do not send a blank SysEx message
                if (sysExMessageLength == 0)
                {
                    return;
                }

                // SysEx messages are two characters long with 1-character space in between them
                // So we add 1 to the message length, so that it is perfectly divisible by 3
                // The loop count tracks the number of individual message pieces
                int loopCount = (sysExMessageLength + 1) / 3;

                // Expecting a string of format "F0 NN NN NN NN.... F7", where NN is a byte in hex
                for (int i = 0; i < loopCount; i++)
                {
                    var messageString = sysExMessage.Substring(3 * i, 2);
                    var messageByte   = Convert.ToByte(messageString, 16);
                    dataWriter.WriteByte(messageByte);
                }
                midiMessageToSend = new MidiSystemExclusiveMessage(dataWriter.DetachBuffer());
                break;

            case MidiMessageType.MidiTimeCode:
                midiMessageToSend = new MidiTimeCodeMessage(Convert.ToByte(GetParameterValue(parameter1)), Convert.ToByte(GetParameterValue(parameter2)));
                break;

            case MidiMessageType.SongPositionPointer:
                midiMessageToSend = new MidiSongPositionPointerMessage(Convert.ToUInt16(GetParameterValue(parameter1)));
                break;

            case MidiMessageType.SongSelect:
                midiMessageToSend = new MidiSongSelectMessage(Convert.ToByte(GetParameterValue(parameter1)));
                break;

            case MidiMessageType.TuneRequest:
                midiMessageToSend = new MidiTuneRequestMessage();
                break;

            case MidiMessageType.TimingClock:
                midiMessageToSend = new MidiTimingClockMessage();
                break;

            case MidiMessageType.Start:
                midiMessageToSend = new MidiStartMessage();
                break;

            case MidiMessageType.Continue:
                midiMessageToSend = new MidiContinueMessage();
                break;

            case MidiMessageType.Stop:
                midiMessageToSend = new MidiStopMessage();
                break;

            case MidiMessageType.ActiveSensing:
                midiMessageToSend = new MidiActiveSensingMessage();
                break;

            case MidiMessageType.SystemReset:
                midiMessageToSend = new MidiSystemResetMessage();
                break;

            case MidiMessageType.None:
            default:
                return;
            }

            // Send the message
            _currentMidiOutputDevice.SendMessage(midiMessageToSend);
            NotifyUser("Message sent successfully");
        }
예제 #10
0
        private void MidiInPort_MessageRecieved(object sender, MidiMessageReceivedEventArgs args)
        {
            stopwatch.Restart();
            IMidiMessage message = args.Message;

            if (message.Type == MidiMessageType.NoteOn)
            {
                MidiNoteOnMessage msg = (MidiNoteOnMessage)message;
                //channels[msg.Channel] = true;
                //DebugChannels();

                if (controlKeys.Contains(msg.Note) && !openControlRecords.ContainsKey(msg.Channel))
                {
                    heapInProgress = true;
                    openControlRecords.Add(msg.Channel, new ChannelRecord(msg.Note));
                }
                else if (!openDownRecords.ContainsKey(msg.Note))
                {
                    heapInProgress = true;
                    openDownRecords.Add(msg.Note, new ChannelRecord(msg.Note));
                }
            }
            else if (message.Type == MidiMessageType.NoteOff)
            {
                MidiNoteOffMessage msg = (MidiNoteOffMessage)message;
                //channels[msg.Channel] = false;
                //DebugChannels();

                if (controlKeys.Contains(msg.Note) && openControlRecords.ContainsKey(msg.Channel))
                {
                    suspendedRecords.Add(openControlRecords[msg.Channel]);

                    openControlRecords.Remove(msg.Channel);
                }
                else if (openDownRecords.ContainsKey(msg.Note))
                {
                    suspendedRecords.Add(openDownRecords[msg.Note]);
                    openDownRecords.Remove(msg.Note);
                }

                if (openControlRecords.Count == 0 && openDownRecords.Count == 0)
                {
                    BeginDebounce();
                }
            }
            else if (message.Type == MidiMessageType.ControlChange)
            {
                MidiControlChangeMessage controlMessage = (MidiControlChangeMessage)message;
                int channel = controlMessage.Channel;

                if (openControlRecords.ContainsKey(channel))
                {
                    switch (controlMessage.Controller)
                    {
                    case 1:
                        openControlRecords[channel].MakeRecord(controlMessage.ControlValue);
                        //Debug.WriteLine(openRecords[channel].ToString());
                        break;

                    default:
                        Debug.WriteLine("Got unexpected control change on controller " + controlMessage.Controller);
                        break;
                    }
                }
            }
        }
예제 #11
0
        /// <summary>
        /// Create a new MIDI message based on the message type and Parameter(s) values,
        /// and send it to the chosen output device
        /// </summary>
        /// <param name="sender">Element that fired the event</param>
        /// <param name="e">Event arguments</param>
        private void SendButton_Clicked(object sender, EventArgs e)
        {
            MidiMessage midiMessageToSend = null;

            switch (this.currentMessageType)
            {
            case MidiEvent.NoteOff:
                midiMessageToSend = new MidiNoteOffMessage(Convert.ToByte(this.Parameter1.SelectedItem), Convert.ToByte(this.Parameter2.SelectedItem), Convert.ToByte(this.Parameter3.SelectedItem));
                break;

            case MidiEvent.NoteOn:
                midiMessageToSend = new MidiNoteOnMessage(Convert.ToByte(this.Parameter1.SelectedItem), Convert.ToByte(this.Parameter2.SelectedItem), Convert.ToByte(this.Parameter3.SelectedItem));
                break;

            case MidiEvent.PAf:
                midiMessageToSend = new MidiPolyphonicKeyPressureMessage(Convert.ToByte(this.Parameter1.SelectedItem), Convert.ToByte(this.Parameter2.SelectedItem), Convert.ToByte(this.Parameter3.SelectedItem));
                break;

            case MidiEvent.CC:
                midiMessageToSend = new MidiControlChangeMessage(Convert.ToByte(this.Parameter1.SelectedItem), Convert.ToByte(this.Parameter2.SelectedItem), Convert.ToByte(this.Parameter3.SelectedItem));
                break;

            case MidiEvent.Program:
                midiMessageToSend = new MidiProgramChangeMessage(Convert.ToByte(this.Parameter1.SelectedItem), Convert.ToByte(this.Parameter2.SelectedItem));
                break;

            case MidiEvent.CAf:
                midiMessageToSend = new MidiChannelPressureMessage(Convert.ToByte(this.Parameter1.SelectedItem), Convert.ToByte(this.Parameter2.SelectedItem));
                break;

            case MidiEvent.Pitch:
                midiMessageToSend = new MidiPitchBendChangeMessage(Convert.ToByte(this.Parameter1.SelectedItem), Convert.ToUInt16(this.Parameter2.SelectedItem));
                break;

            case MidiEvent.SysEx1:
                var dataWriter         = new List <byte>();
                var sysExMessage       = this.SysExMessageContent.Text;
                var sysExMessageLength = sysExMessage.Length;

                // Do not send a blank SysEx message
                if (sysExMessageLength == 0)
                {
                    return;
                }

                // SysEx messages are two characters long with 1-character space in between them
                // So we add 1 to the message length, so that it is perfectly divisible by 3
                // The loop count tracks the number of individual message pieces
                int loopCount = (sysExMessageLength + 1) / 3;

                // Expecting a string of format "F0 NN NN NN NN.... F7", where NN is a byte in hex
                for (int i = 0; i < loopCount; i++)
                {
                    var messageString = sysExMessage.Substring(3 * i, 2);
                    var messageByte   = Convert.ToByte(messageString, 16);
                    dataWriter.Add(messageByte);
                }
                midiMessageToSend = new MidiSystemExclusiveMessage(dataWriter.ToArray());
                break;

            case MidiEvent.MtcQuarterFrame:
                midiMessageToSend = new MidiTimeCodeMessage(Convert.ToByte(this.Parameter1.SelectedItem), Convert.ToByte(this.Parameter2.SelectedItem));
                break;

            case MidiEvent.SongPositionPointer:
                midiMessageToSend = new MidiSongPositionPointerMessage(Convert.ToUInt16(this.Parameter1.SelectedItem));
                break;

            case MidiEvent.SongSelect:
                midiMessageToSend = new MidiSongSelectMessage(Convert.ToByte(this.Parameter1.SelectedItem));
                break;

            case MidiEvent.TuneRequest:
                midiMessageToSend = new MidiTuneRequestMessage();
                break;

            case MidiEvent.MidiClock:
                midiMessageToSend = new MidiTimingClockMessage();
                break;

            case MidiEvent.MidiStart:
                midiMessageToSend = new MidiStartMessage();
                break;

            case MidiEvent.MidiContinue:
                midiMessageToSend = new MidiContinueMessage();
                break;

            case MidiEvent.MidiStop:
                midiMessageToSend = new MidiStopMessage();
                break;

            case MidiEvent.ActiveSense:
                midiMessageToSend = new MidiActiveSensingMessage();
                break;

            case MidiEvent.Reset:
                midiMessageToSend = new MidiSystemResetMessage();
                break;

            default:
                return;
            }

            // Send the message
            _synthesizer.SendMessage(midiMessageToSend);
            //this.rootPage.NotifyUser("Message sent successfully", NotifyType.StatusMessage);
        }
        /// <summary>
        /// Create a new MIDI message based on the message type and parameter(s) values,
        /// and send it to the chosen output device
        /// </summary>
        /// <param name="sender">Element that fired the event</param>
        /// <param name="e">Event arguments</param>
        private void sendButton_Click(object sender, Windows.UI.Xaml.RoutedEventArgs e)
        {
            IMidiMessage midiMessageToSend = null;

            switch (this.currentMessageType)
            {
                case MidiMessageType.NoteOff:
                    midiMessageToSend = new MidiNoteOffMessage(Convert.ToByte(this.parameter1.SelectedValue), Convert.ToByte(this.parameter2.SelectedValue), Convert.ToByte(this.parameter3.SelectedValue));
                    break;
                case MidiMessageType.NoteOn:
                    midiMessageToSend = new MidiNoteOnMessage(Convert.ToByte(this.parameter1.SelectedValue), Convert.ToByte(this.parameter2.SelectedValue), Convert.ToByte(this.parameter3.SelectedValue));
                    break;
                case MidiMessageType.PolyphonicKeyPressure:
                    midiMessageToSend = new MidiPolyphonicKeyPressureMessage(Convert.ToByte(this.parameter1.SelectedValue), Convert.ToByte(this.parameter2.SelectedValue), Convert.ToByte(this.parameter3.SelectedValue));
                    break;
                case MidiMessageType.ControlChange:
                    midiMessageToSend = new MidiControlChangeMessage(Convert.ToByte(this.parameter1.SelectedValue), Convert.ToByte(this.parameter2.SelectedValue), Convert.ToByte(this.parameter3.SelectedValue));
                    break;
                case MidiMessageType.ProgramChange:
                    midiMessageToSend = new MidiProgramChangeMessage(Convert.ToByte(this.parameter1.SelectedValue), Convert.ToByte(this.parameter2.SelectedValue));
                    break;
                case MidiMessageType.ChannelPressure:
                    midiMessageToSend = new MidiChannelPressureMessage(Convert.ToByte(this.parameter1.SelectedValue), Convert.ToByte(this.parameter2.SelectedValue));
                    break;
                case MidiMessageType.PitchBendChange:
                    midiMessageToSend = new MidiPitchBendChangeMessage(Convert.ToByte(this.parameter1.SelectedValue), Convert.ToUInt16(this.parameter2.SelectedValue));
                    break;
                case MidiMessageType.SystemExclusive:
                    var dataWriter = new DataWriter();
                    var sysExMessage = this.sysExMessageContent.Text;
                    var sysExMessageLength = sysExMessage.Length;

                    // Do not send a blank SysEx message
                    if (sysExMessageLength == 0)
                    {
                        return;
                    }

                    // SysEx messages are two characters long with 1-character space in between them
                    // So we add 1 to the message length, so that it is perfectly divisible by 3
                    // The loop count tracks the number of individual message pieces
                    int loopCount = (sysExMessageLength + 1) / 3;

                    // Expecting a string of format "F0 NN NN NN NN.... F7", where NN is a byte in hex
                    for (int i = 0; i < loopCount; i++)
                    {
                        var messageString = sysExMessage.Substring(3 * i, 2);
                        var messageByte = Convert.ToByte(messageString, 16);
                        dataWriter.WriteByte(messageByte);
                    }
                    midiMessageToSend = new MidiSystemExclusiveMessage(dataWriter.DetachBuffer());
                    break;
                case MidiMessageType.MidiTimeCode:
                    midiMessageToSend = new MidiTimeCodeMessage(Convert.ToByte(this.parameter1.SelectedValue), Convert.ToByte(this.parameter2.SelectedValue));
                    break;
                case MidiMessageType.SongPositionPointer:
                    midiMessageToSend = new MidiSongPositionPointerMessage(Convert.ToUInt16(this.parameter1.SelectedValue));
                    break;
                case MidiMessageType.SongSelect:
                    midiMessageToSend = new MidiSongSelectMessage(Convert.ToByte(this.parameter1.SelectedValue));
                    break;
                case MidiMessageType.TuneRequest:
                    midiMessageToSend = new MidiTuneRequestMessage();
                    break;
                case MidiMessageType.TimingClock:
                    midiMessageToSend = new MidiTimingClockMessage();
                    break;
                case MidiMessageType.Start:
                    midiMessageToSend = new MidiStartMessage();
                    break;
                case MidiMessageType.Continue:
                    midiMessageToSend = new MidiContinueMessage();
                    break;
                case MidiMessageType.Stop:
                    midiMessageToSend = new MidiStopMessage();
                    break;
                case MidiMessageType.ActiveSensing:
                    midiMessageToSend = new MidiActiveSensingMessage();
                    break;
                case MidiMessageType.SystemReset:
                    midiMessageToSend = new MidiSystemResetMessage();
                    break;
                case MidiMessageType.None:
                default:
                    return;
            }

            // Send the message
            this.currentMidiOutputDevice.SendMessage(midiMessageToSend);
            this.rootPage.NotifyUser("Message sent successfully", NotifyType.StatusMessage);
        }
예제 #13
0
        /// <summary>
        /// Eventhandler for key released at the keyboard.
        /// The specific key is extracted and the according pitch is found.
        /// A MIDI message Note Off is created from the channel field and velocity field.
        /// The Note Off message is send to the MIDI output device
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Key_PointerReleased(object sender, PointerRoutedEventArgs e)
        {
            // Field to hold the pitch of the note
            byte note;

            // Extract the key being pressed
            Rectangle keyPressed = (Rectangle)sender;

            // Get the name of the key and store it in a string, keyPressedName
            string keyPressedName = keyPressed.Name;

            if (keyPressedName.Length != 4)
            {
                keyPressed.Fill = new SolidColorBrush(Color.FromArgb(220, 0, 0, 0));
            }
            else
            {
                keyPressed.Fill = new SolidColorBrush(Color.FromArgb(220, 255, 255, 255));
            }

            // Switch/Case to set the pitch depending of the key pressed
            switch (keyPressedName)
            {
            case "AKey":
                note = (byte)(60 + (octaveInterval * 12));
                break;

            case "ASharpKey":
                note = (byte)(61 + (octaveInterval * 12));
                break;

            case "BKey":
                note = (byte)(62 + (octaveInterval * 12));
                break;

            case "BSharpKey":
                note = (byte)(63 + (octaveInterval * 12));
                break;

            case "CKey":
                note = (byte)(64 + (octaveInterval * 12));
                break;

            case "CSharpKey":
                note = (byte)(65 + (octaveInterval * 12));
                break;

            case "DKey":
                note = (byte)(66 + (octaveInterval * 12));
                break;

            case "DSharpKey":
                note = (byte)(67 + (octaveInterval * 12));
                break;

            case "EKey":
                note = (byte)(68 + (octaveInterval * 12));
                break;

            case "ESharpKey":
                note = (byte)(69 + (octaveInterval * 12));
                break;

            default:
                note = (byte)(60 + (octaveInterval * 12));
                break;
            }

            // Create the Note Off message to send to the MIDI output device
            IMidiMessage midiMessageToSend = new MidiNoteOffMessage(channel, note, velocity);

            // Send the Note Off MIDI message to the midiOutPort
            midiOutPort.SendMessage(midiMessageToSend);
        }