Ejemplo n.º 1
0
        //Paint Events
        public void PaintEvents(PaintEventArgs e)
        {
            //Get a copy of currentMidiObjects Events
            MidiEvent[] CurrentMidiEvents = new MidiEvent[0];
            Array.Resize(ref CurrentMidiEvents, CurrentMidiObject.Track.Events.Length);
            Array.Copy(CurrentMidiObject.Track.Events, CurrentMidiEvents, CurrentMidiObject.Track.Events.Length);

            if (CurrentMidiEvents != null && CurrentMidiEvents.Length > 0 && CurrentMidiEvents[0] != null)
            {
                MidiEvent CurrentEvent = null;
                for (int EventIndex = 0; EventIndex <= CurrentMidiEvents.Length - 1; EventIndex++)
                {
                    CurrentEvent = CurrentMidiEvents[EventIndex];
                    //Paint Tempo Events : Paint all TempoEvents before NoteDown Events, for depth
                    if (CurrentEvent is TempoMidiEvent)
                    {
                        TempoMidiEvent CurrentTempoEvent = (TempoMidiEvent)CurrentEvent;
                        e.Graphics.FillRectangle(Brushes.Yellow, (CurrentTempoEvent.CellPosition * CellWidth) + (CellWidth / 2), 0, (CellWidth / 2), ROWCOUNT * CellHeight);
                    }
                    //Paint InstrumentEvents : Paint all InstrumentEvents before NoteDown Events, for depth
                    if (CurrentEvent is InstrumentMidiEvent)
                    {
                        InstrumentMidiEvent CurrentTempoEvent = (InstrumentMidiEvent)CurrentEvent;
                        e.Graphics.FillRectangle(Brushes.Red, (CurrentTempoEvent.CellPosition * CellWidth), 0, (CellWidth / 2), ROWCOUNT * CellHeight);
                    }
                }
                //for each Note
                for (int EventIndex = 0; EventIndex <= CurrentMidiEvents.Length - 1; EventIndex++)
                {
                    CurrentEvent = CurrentMidiEvents[EventIndex];
                    //Paint note events
                    if (CurrentEvent.Type == NOTE_DOWN)
                    {
                        //Paint notes
                        e.Graphics.FillRectangle(NoteFill, CurrentEvent.CellPosition * CellWidth, (127 - CurrentEvent.Paramater1) * CellHeight, CurrentEvent.Length * CellWidth, CellHeight);
                        e.Graphics.DrawRectangle(NoteOutline, CurrentEvent.CellPosition * CellWidth, (127 - CurrentEvent.Paramater1) * CellHeight, CurrentEvent.Length * CellWidth, CellHeight);
                    }
                }
                //for each selected note
                if (SelectedEvents != null && SelectedEvents.Length > 0 && SelectedEvents[0] != null)
                {
                    for (int EventIndex = 0; EventIndex <= SelectedEvents.Length - 1; EventIndex++)
                    {
                        CurrentEvent = SelectedEvents[EventIndex];
                        //Paint note events
                        if (CurrentEvent.Type == NOTE_DOWN)
                        {
                            //Paint notes
                            e.Graphics.FillRectangle(Brushes.Red, CurrentEvent.CellPosition * CellWidth, (127 - CurrentEvent.Paramater1) * CellHeight, CurrentEvent.Length * CellWidth, CellHeight);
                            e.Graphics.DrawRectangle(Pens.Black, CurrentEvent.CellPosition * CellWidth, (127 - CurrentEvent.Paramater1) * CellHeight, CurrentEvent.Length * CellWidth, CellHeight);
                        }
                    }
                }
                e.Dispose();
            }
        }
Ejemplo n.º 2
0
        //Validate Instrument event, to avoid overlapping
        public Boolean ValidateInstrumentPlacement(MidiEvent[] CurrentMidiEvents, MidiEvent CurrentEvent)
        {
            //Caste current event to TempoEvent
            InstrumentMidiEvent CurrentTempoEvent = (InstrumentMidiEvent)CurrentEvent;

            //If there are no events at the moment, return true
            if (CurrentMidiEvents.Length == 0 || CurrentMidiEvents[0] == null)
            {
                return(true);
            }
            for (int i = 0; i < CurrentMidiEvents.Length; i++)
            {
                //for each event that is a InstrumentMidiEvent, check for overlapping location
                if (CurrentMidiEvents[i] is InstrumentMidiEvent &&
                    CurrentMidiEvents[i].CellPosition == CurrentTempoEvent.CellPosition)
                {
                    //if there is an overlap, return false. Event will not be placed
                    return(false);
                }
            }
            //If there is no instrument event here, return true
            return(true);
        }
Ejemplo n.º 3
0
        //Determine the Instrument number at a certain cell
        public byte InstrumentAtPosition(int MyCellPosition)
        {
            byte Instrument = 0;

            //Get a copy of currentMidiObjects Events
            MidiEvent[] CurrentMidiEvents = new MidiEvent[0];
            Array.Resize(ref CurrentMidiEvents, CurrentMidiObject.Track.Events.Length);
            Array.Copy(CurrentMidiObject.Track.Events, CurrentMidiEvents, CurrentMidiObject.Track.Events.Length);
            //check each event
            for (int EventIndex = 0; EventIndex < CurrentMidiEvents.Length; EventIndex++)
            {
                //Update Current Instrument, to be the Instrument closest to the mouseposition, but still to the left(time)
                if (CurrentMidiEvents[EventIndex] is InstrumentMidiEvent && CurrentMidiEvents[EventIndex].CellPosition <= MyCellPosition)
                {
                    InstrumentMidiEvent CurrentInstrumentEvent = (InstrumentMidiEvent)CurrentMidiEvents[EventIndex];
                    //Parameter1 Holds the Instrument value
                    Instrument = (CurrentInstrumentEvent.Paramater1);
                }
            }
            //If no Instrument event is found, midi assumes instrument 0, Acoustice Grand Piano

            return(Instrument);
        }
Ejemplo n.º 4
0
        //Generate Midi Event Bytes, Calculate Delta times in bytes.
        public void GenerateMidiEventByteArray(MidiEvent[] MidiEventArray)
        {
            int ByteIndex = 0;

            for (int EventIndex = 0; EventIndex <= MidiEventArray.Length - 1; EventIndex++)
            {
                //Convert Delta times to Big-Endian bytes (max 4 bytes)
                if ((MidiEventArray[EventIndex].Delta >> SEVENSHIFT * 3) > 0)
                {
                    Array.Resize(ref TrackChunkBytes, ByteIndex + 1);
                    TrackChunkBytes[ByteIndex] = Convert.ToByte(128 | (MidiEventArray[EventIndex].Delta >> SEVENSHIFT * 3));
                    ByteIndex += 1;
                }

                if ((MidiEventArray[EventIndex].Delta >> SEVENSHIFT * 2) > 0)
                {
                    Array.Resize(ref TrackChunkBytes, ByteIndex + 1);
                    TrackChunkBytes[ByteIndex] = Convert.ToByte(128 | (MidiEventArray[EventIndex].Delta >> SEVENSHIFT * 2));
                    ByteIndex += 1;
                }

                if ((MidiEventArray[EventIndex].Delta >> SEVENSHIFT) > 0)
                {
                    Array.Resize(ref TrackChunkBytes, ByteIndex + 1);
                    TrackChunkBytes[ByteIndex] = Convert.ToByte(128 | MidiEventArray[EventIndex].Delta >> SEVENSHIFT);
                    ByteIndex += 1;
                }
                //Final byte Delta Time
                Array.Resize(ref TrackChunkBytes, ByteIndex + 1);
                TrackChunkBytes[ByteIndex] = Convert.ToByte(127 & (MidiEventArray[EventIndex].Delta));
                ByteIndex += 1;
                //Decide how to write event data
                if (MidiEventArray[EventIndex] is TempoMidiEvent)
                {
                    //Caste Event
                    TempoMidiEvent CurrentTempoEvent = (TempoMidiEvent)MidiEventArray[EventIndex];
                    //Meta Event Number
                    Array.Resize(ref TrackChunkBytes, ByteIndex + 1);
                    TrackChunkBytes[ByteIndex] = CurrentTempoEvent.MetaEventNumber;
                    ByteIndex += 1;

                    //Meta Event Type
                    Array.Resize(ref TrackChunkBytes, ByteIndex + 1);
                    TrackChunkBytes[ByteIndex] = CurrentTempoEvent.MetaEventType;
                    ByteIndex += 1;
                    //Meta Event Data Length
                    Array.Resize(ref TrackChunkBytes, ByteIndex + 1);
                    TrackChunkBytes[ByteIndex] = CurrentTempoEvent.MetaEventDataLength;
                    ByteIndex += 1;
                    //Quarter Note Time
                    Array.Resize(ref TrackChunkBytes, ByteIndex + 1);
                    TrackChunkBytes[ByteIndex] = Convert.ToByte(255 & (CurrentTempoEvent.QuarterNoteTime >> 16));
                    ByteIndex += 1;
                    //Quarter Note Time
                    Array.Resize(ref TrackChunkBytes, ByteIndex + 1);
                    TrackChunkBytes[ByteIndex] = Convert.ToByte(255 & (CurrentTempoEvent.QuarterNoteTime >> 8));
                    ByteIndex += 1;
                    //Quarter Note Time
                    Array.Resize(ref TrackChunkBytes, ByteIndex + 1);
                    TrackChunkBytes[ByteIndex] = Convert.ToByte(255 & (CurrentTempoEvent.QuarterNoteTime));
                    ByteIndex += 1;
                }
                else if (MidiEventArray[EventIndex] is InstrumentMidiEvent)
                {
                    //Caste Event
                    InstrumentMidiEvent CurrentTempoEvent = (InstrumentMidiEvent)MidiEventArray[EventIndex];
                    //Instrument Event Number :channel default zero
                    Array.Resize(ref TrackChunkBytes, ByteIndex + 1);
                    TrackChunkBytes[ByteIndex] = Convert.ToByte(CurrentTempoEvent.Type << 4);
                    ByteIndex += 1;

                    //Meta Event Type
                    Array.Resize(ref TrackChunkBytes, ByteIndex + 1);
                    TrackChunkBytes[ByteIndex] = CurrentTempoEvent.Paramater1;
                    ByteIndex += 1;
                }
                else
                {
                    //Event Type & Channel(Zero) TODO:This defaults channel to zero always
                    Array.Resize(ref TrackChunkBytes, ByteIndex + 1);
                    TrackChunkBytes[ByteIndex] = Convert.ToByte(MidiEventArray[EventIndex].Type << 4);
                    ByteIndex += 1;

                    //Param1
                    Array.Resize(ref TrackChunkBytes, ByteIndex + 1);
                    TrackChunkBytes[ByteIndex] = MidiEventArray[EventIndex].Paramater1;
                    ByteIndex += 1;
                    //Param2
                    Array.Resize(ref TrackChunkBytes, ByteIndex + 1);
                    TrackChunkBytes[ByteIndex] = MidiEventArray[EventIndex].Paramater2;
                    ByteIndex += 1;
                }
            }
            //Add end of Track Event
            Array.Resize(ref TrackChunkBytes, ByteIndex + 6);
            TrackChunkBytes[ByteIndex] = EndOfTrack[0];
            ByteIndex += 1;
            TrackChunkBytes[ByteIndex] = EndOfTrack[1];
            ByteIndex += 1;
            TrackChunkBytes[ByteIndex] = EndOfTrack[2];
            ByteIndex += 1;
            TrackChunkBytes[ByteIndex] = EndOfTrack[3];
            ByteIndex += 1;
            TrackChunkBytes[ByteIndex] = EndOfTrack[4];
            ByteIndex += 1;
            TrackChunkBytes[ByteIndex] = EndOfTrack[5];
        }
Ejemplo n.º 5
0
        //Create TrackChunk Object from Array of Bytes
        public void TrackChunkFromBytes(byte[] TrackBytes)
        {
            //MidiEvent
            int   Delta = 0;
            sbyte EventType;
            sbyte MidiChannel;
            byte  Param1;
            byte  Param2;
            //TempoEvent
            int MicroSecondsPerQuarterNote = 1;
            //InstrumentEvent
            byte InstrumentNumber = 1;

            MidiEvent[] OpenedEvents   = new MidiEvent[1];
            Boolean     DeltaRetrieved = false;
            int         NextEventIndex = 0;
            byte        NextByteValue;

            for (int ByteIndex = TRACKHEADERLENGTH; ByteIndex < TrackBytes.Length - 1; ByteIndex++)
            {
                Delta = 0;
                while (!(DeltaRetrieved))
                {
                    NextByteValue = TrackBytes[ByteIndex];
                    if ((NextByteValue) >= 128)
                    {
                        Delta = NextByteValue & 127;
                        Delta = Delta << SHIFT;
                    }
                    else
                    {
                        Delta          = Delta | NextByteValue;
                        DeltaRetrieved = true;
                    }
                    ByteIndex++;
                }
                DeltaRetrieved = false;

                NextByteValue = TrackBytes[ByteIndex];
                //If its a Meta Event
                if (NextByteValue == 0xff)
                {
                    ByteIndex++;
                    NextByteValue = TrackBytes[ByteIndex];
                    if ((NextByteValue == 0x2F))
                    {
                        //EOT found
                        break;
                    }
                    ByteIndex++;
                    NextByteValue = TrackBytes[ByteIndex];
                    ByteIndex++;
                    MicroSecondsPerQuarterNote = TrackBytes[ByteIndex] << 8;
                    ByteIndex++;
                    MicroSecondsPerQuarterNote = (MicroSecondsPerQuarterNote | TrackBytes[ByteIndex]) << 8;
                    ByteIndex++;
                    MicroSecondsPerQuarterNote = (MicroSecondsPerQuarterNote | TrackBytes[ByteIndex]);

                    if (OpenedEvents[0] == null)
                    {
                    }
                    else
                    {
                        Array.Resize(ref OpenedEvents, OpenedEvents.Length + 1);
                    }
                    OpenedEvents[NextEventIndex] = new TempoMidiEvent(Delta, MicroSecondsPerQuarterNote);
                    NextEventIndex++;
                }
                //if its an instrument change event
                else if (NextByteValue == 0xC0)
                {
                    MidiChannel = Convert.ToSByte(0x0f & NextByteValue << 4);
                    ByteIndex++;
                    NextByteValue    = TrackBytes[ByteIndex];
                    InstrumentNumber = NextByteValue;
                    if (OpenedEvents[0] == null)
                    {
                        //Do Nothing. Opened events are empty and the first element is free
                    }
                    else //Resize the array for the extra event
                    {
                        Array.Resize(ref OpenedEvents, OpenedEvents.Length + 1);
                    }
                    OpenedEvents[NextEventIndex] = new InstrumentMidiEvent(Delta, 0, MidiChannel, InstrumentNumber);
                    NextEventIndex++;
                }
                //Other Midi Event
                else
                {
                    EventType = Convert.ToSByte(NextByteValue >> 4);
                    //No ByteIndex++ because EventType& MidiChannel are stored in same byte
                    MidiChannel = Convert.ToSByte(NextByteValue & 0xf);
                    ByteIndex++;

                    NextByteValue = TrackBytes[ByteIndex];
                    Param1        = NextByteValue;
                    ByteIndex++;

                    NextByteValue = TrackBytes[ByteIndex];
                    Param2        = NextByteValue;

                    if (OpenedEvents[0] == null)
                    {
                    }
                    else
                    {
                        Array.Resize(ref OpenedEvents, OpenedEvents.Length + 1);
                    }
                    OpenedEvents[NextEventIndex] = new MidiEvent(0, 0, Delta, EventType, MidiChannel, Param1, Param2);
                    NextEventIndex++;
                }
            }
            CalculateScorePositionFromDeltaTimes(OpenedEvents, MidiHeaderChunk.Ticks);
            CalculateNoteDownLengths(OpenedEvents);
            MidiTrackChunk = new TrackChunk(OpenedEvents);
        }
Ejemplo n.º 6
0
        //Remove Instrument/Tempo/Midi Event from CurrentMidi Object
        public void DeleteEvent(MidiEvent[] CurrentMidiEvents, MouseEventArgs e)
        {
            switch (e.Button)
            {
            case MouseButtons.Left:

                for (int EventIndex = 0; EventIndex < CurrentMidiEvents.Length; EventIndex++)
                {
                    #region Search for Note to Delete
                    if ((CurrentMidiEvents[EventIndex].Type == NOTE_DOWN &&
                         CurrentMidiEvents[EventIndex].Paramater1 == 127 - CurrentCellYPosition) &&
                        (CurrentCellXPosition >= CurrentMidiEvents[EventIndex].CellPosition &&
                         CurrentCellXPosition < CurrentMidiEvents[EventIndex].CellPosition + CurrentMidiEvents[EventIndex].Length))
                    //if the current Cell is within the bounds of a note
                    {
                        for (int NoteUpIndex = EventIndex + 1; NoteUpIndex < (CurrentMidiEvents.Length); NoteUpIndex++)
                        {
                            if (CurrentMidiEvents[NoteUpIndex].Type == 0x08 && (CurrentMidiEvents[NoteUpIndex].Paramater1 == CurrentMidiEvents[EventIndex].Paramater1))
                            {
                                for (int i = NoteUpIndex; i < CurrentMidiEvents.Length - 1; i++)
                                {
                                    CurrentMidiEvents[i] = CurrentMidiEvents[i + 1];
                                }
                                for (int i = EventIndex; i < CurrentMidiEvents.Length - 2; i++)
                                {
                                    CurrentMidiEvents[i] = CurrentMidiEvents[i + 1];
                                }
                                if (CurrentMidiEvents.Length == 2)
                                {
                                    Array.Resize(ref CurrentMidiEvents, 0);
                                }
                                else
                                {
                                    Array.Resize(ref CurrentMidiEvents, CurrentMidiEvents.Length - 2);
                                }
                                //finish
                                EventIndex = CurrentMidiEvents.Length;
                                break;
                            }
                        }
                    }
                    if (EventIndex == CurrentMidiEvents.Length)
                    {
                        break;
                    }
                    #endregion
                    #region Search Instrument Event
                    if (CurrentMidiEvents[EventIndex] is InstrumentMidiEvent && EventIndex != CurrentMidiEvents.Length)
                    //if the current Cell is within the bounds of a note
                    {
                        InstrumentMidiEvent CurrentInstrumentEvent = (InstrumentMidiEvent)CurrentMidiEvents[EventIndex];
                        if (CurrentInstrumentEvent.CellPosition == CurrentCellXPosition)
                        {
                            for (int i = EventIndex; i < CurrentMidiEvents.Length - 1; i++)
                            {
                                CurrentMidiEvents[i] = CurrentMidiEvents[i + 1];
                            }
                            if (CurrentMidiEvents.Length == 1)
                            {
                                Array.Resize(ref CurrentMidiEvents, 0);
                            }
                            else
                            {
                                Array.Resize(ref CurrentMidiEvents, CurrentMidiEvents.Length - 1);
                            }
                            //finish
                            EventIndex = CurrentMidiEvents.Length;
                            break;
                        }
                    }
                    if (EventIndex == CurrentMidiEvents.Length)
                    {
                        break;
                    }
                    #endregion
                }
                //Update the Track Events
                CurrentMidiObject.Track.Events = CurrentMidiEvents;
                break;

            case MouseButtons.Right:
                for (int EventIndex = 0; EventIndex < CurrentMidiEvents.Length; EventIndex++)
                {
                    #region Search tempo event
                    if (CurrentMidiEvents[EventIndex] is TempoMidiEvent && EventIndex != CurrentMidiEvents.Length)
                    //if the current Cell is within the bounds of a note
                    {
                        TempoMidiEvent CurrentTempoEvent = (TempoMidiEvent)CurrentMidiEvents[EventIndex];
                        if (CurrentTempoEvent.CellPosition == CurrentCellXPosition)
                        {
                            for (int i = EventIndex; i < CurrentMidiEvents.Length - 1; i++)
                            {
                                CurrentMidiEvents[i] = CurrentMidiEvents[i + 1];
                            }
                            if (CurrentMidiEvents.Length == 1)
                            {
                                Array.Resize(ref CurrentMidiEvents, 0);
                            }
                            else
                            {
                                Array.Resize(ref CurrentMidiEvents, CurrentMidiEvents.Length - 1);
                            }
                            //finish
                            EventIndex = CurrentMidiEvents.Length;
                            break;
                        }
                    }
                    if (EventIndex == CurrentMidiEvents.Length)
                    {
                        break;
                    }
                    #endregion
                }
                //Update the Track Events
                CurrentMidiObject.Track.Events = CurrentMidiEvents;
                break;

            default:
                break;
            }
        }