private void UpdateMidiEvents()
        {
            var Result = from c in this.Data.data
                         where
                         c.Arrangement == this.SelectedArrangement &&
                         c.ChordType == this.SelectedChordFamily &&
                         c.Instrument == this.SelectedInstrument &&
                         c.Part == this.SelectedPart
                         select c;

            lwMessages.Items.Clear();

            foreach (var item in Result)
            {
                ListViewItem lwi = new ListViewItem(StyleTime.FromStyleMessage(item.Message, this.Data).ToString());

                MidiMessage msg = item.Message;
                lwi.Tag = item;

                lwi.SubItems.Add(msg.MessageType.ToString());
                lwi.SubItems.Add(msg.Channel.ToString());

                switch (msg.MessageType)
                {
                case MidiMessageType.ControlChange:
                    TomiSoft.RolandStyleReader.ControlChangeMessage ccm = (TomiSoft.RolandStyleReader.ControlChangeMessage)msg;
                    lwi.SubItems.Add(ccm.Control.ToString());
                    lwi.SubItems.Add(ccm.Value.ToString());
                    break;

                case MidiMessageType.ProgramChange:
                    TomiSoft.RolandStyleReader.ProgramChangeMessage pcm = (TomiSoft.RolandStyleReader.ProgramChangeMessage)msg;
                    lwi.SubItems.Add(pcm.MSB.ToString());
                    lwi.SubItems.Add(pcm.LSB.ToString());
                    lwi.SubItems.Add(pcm.Program.ToString());
                    break;

                case MidiMessageType.Note:
                    TomiSoft.RolandStyleReader.NoteMessage nm = (TomiSoft.RolandStyleReader.NoteMessage)msg;
                    lwi.SubItems.Add(nm.Name + " " + nm.Octave);
                    lwi.SubItems.Add(nm.Velocity.ToString());
                    lwi.SubItems.Add(nm.Length.ToString());
                    break;
                }

                lwMessages.Items.Add(lwi);
            }
        }
        private void RenderMessages()
        {
            lwMessages.Items.Clear();

            try {
                var Messages = from Current in this.data.data
                               where
                               Current.Arrangement == (this.IsBasic ? Arrangement.Basic : Arrangement.Advanced) &&
                               Current.Part == this.Part &&
                               Current.Instrument == this.instr &&
                               Current.ChordType == this.ctype
                               select Current;

                foreach (StyleEntry Entry in Messages)
                {
                    var msg = Entry.Message;

                    ListViewItem lwi = new ListViewItem(StyleTime.FromStyleMessage(msg, this.data).ToString());
                    lwi.SubItems.Add(msg.MessageType.ToString());
                    lwi.SubItems.Add(msg.Channel.ToString());

                    switch (msg.MessageType)
                    {
                    case MidiMessageType.ControlChange:
                        TomiSoft.RolandStyleReader.ControlChangeMessage ccm = (TomiSoft.RolandStyleReader.ControlChangeMessage)msg;
                        lwi.SubItems.Add(ccm.Control.ToString());
                        lwi.SubItems.Add(ccm.Value.ToString());
                        break;

                    case MidiMessageType.ProgramChange:
                        TomiSoft.RolandStyleReader.ProgramChangeMessage pcm = (TomiSoft.RolandStyleReader.ProgramChangeMessage)msg;
                        lwi.SubItems.Add(pcm.MSB.ToString());
                        lwi.SubItems.Add(pcm.LSB.ToString());
                        lwi.SubItems.Add(pcm.Program.ToString());
                        break;

                    case MidiMessageType.Note:
                        TomiSoft.RolandStyleReader.NoteMessage nm = (TomiSoft.RolandStyleReader.NoteMessage)msg;
                        lwi.SubItems.Add(nm.Name + " " + nm.Octave);
                        lwi.SubItems.Add(nm.Velocity.ToString());
                        lwi.SubItems.Add(nm.Length.ToString());
                        break;
                    }

                    lwMessages.Items.Add(lwi);
                }
            }
            catch (NoteValueOutOfRangeException) {
                MessageBox.Show(
                    "Note number must be in range 0-127",
                    "Error",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error
                    );
            }
            catch (NoteVelocityOutOfRangeException) {
                MessageBox.Show(
                    "Note velocity must be in range 0-127",
                    "Error",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error
                    );
            }
            catch (Exception) {
                MessageBox.Show(
                    "The style does not contain information for the selected part",
                    "Error",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error
                    );
            }
        }
        private void btnPlay_Click(object sender, EventArgs e)
        {
            dev.Open();
            Clock clock = new Clock(this.data.Tempo);

            bool ProgramSent = false;

            if (this.instr == TomiSoft.RolandStyleReader.Instrument.Drum)
            {
                dev.SendProgramChange(Channel.Channel10, Midi.Instrument.SteelDrums);
                ProgramSent = true;
            }
            else if (this.instr == TomiSoft.RolandStyleReader.Instrument.Bass)
            {
                dev.SendProgramChange(Channel.Channel2, Midi.Instrument.AcousticBass);
                ProgramSent = true;
            }

            float LastMsgTime = 0;
            int   LastTime    = 0;

            try {
                var Messages = from Current in this.data.data
                               where
                               Current.Arrangement == (this.IsBasic ? Arrangement.Basic : Arrangement.Advanced) &&
                               Current.Part == this.Part &&
                               Current.Instrument == this.instr &&
                               Current.ChordType == this.ctype
                               select Current;

                foreach (var Entry in Messages)
                {
                    if (Entry.Message.MessageType == MidiMessageType.Note)
                    {
                        clock.Schedule(this.ToMessage(Entry.Message, dev, clock, out LastMsgTime));
                        LastTime = Entry.Message.TotalTime + ((TomiSoft.RolandStyleReader.NoteMessage)Entry.Message).Length;
                    }

                    else if (Entry.Message.MessageType == MidiMessageType.ProgramChange)
                    {
                        if (!ProgramSent)
                        {
                            TomiSoft.RolandStyleReader.ProgramChangeMessage msg = (TomiSoft.RolandStyleReader.ProgramChangeMessage)Entry.Message;
                            dev.SendProgramChange(Channel.Channel4, (Midi.Instrument)msg.Program);
                        }
                    }
                }
            }
            catch (NoteValueOutOfRangeException) {
                MessageBox.Show(
                    "Note number must be in range 0-127",
                    "Error",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error
                    );
                return;
            }
            catch (NoteVelocityOutOfRangeException) {
                MessageBox.Show(
                    "Note velocity must be in range 0-127",
                    "Error",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error
                    );
                return;
            }
            catch (Exception) {
                MessageBox.Show(
                    "The style does not contain information for the selected part",
                    "Error",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error
                    );
                return;
            }

            pbPlaybackPosition.Maximum = LastTime;

            clock.Start();

            while (clock.Time <= LastMsgTime)
            {
                System.Threading.Thread.Sleep(50);

                StyleTime t = StyleTime.FromStyleTimestamp((int)(clock.Time * 120), this.data.Measure);
                lFriendlyTime.Text = String.Format("{0}.{1}.{2}", t.Bar, t.Beat, t.ClockPulseTime);
                lTotalTime.Text    = t.RawTime.ToString();

                pbBeat.Value             = t.Beat;
                pbPlaybackPosition.Value = (t.RawTime > pbPlaybackPosition.Maximum) ? pbPlaybackPosition.Maximum : t.RawTime;
                Application.DoEvents();
            }

            clock.Stop();
            dev.Close();

            pbBeat.Value             = 0;
            pbPlaybackPosition.Value = 0;
            lFriendlyTime.Text       = "0.0.0";
            lTotalTime.Text          = "0";
        }