Пример #1
0
        public static bool IsInSameMeasure(MIDIEventHelper a, MIDIEventHelper b)
        {
            int measure_a = Mathf.FloorToInt(a.TimeMeasures);
            int measure_b = Mathf.FloorToInt(b.TimeMeasures);

            return(measure_a == measure_b);
        }
Пример #2
0
        public bool GetEvent(int index, out MIDIEventHelper @event)
        {
            bool result = index >= 0 && index < _Events.Count;

            if (result)
            {
                @event = _Events[index];
            }
            else
            {
                @event = null;
            }
            return(result);
        }
Пример #3
0
        public MIDIEventList(MidiData midi_data, TrackChunk track, MIDIEventFilter filter)
        {
            // TODO: get beats per measure by reading all
            // Midi.Events.MetaEvents.TimeSignatureEvents
            // along with the notes in the track (i.e.
            // time signature changes, etc.)
            float beats_per_measure = 4f;

            // Calculate the time scale as the reciprocal
            // of the MIDI time_division
            // time_division is also known as PPQ
            // https://en.wikipedia.org/wiki/Pulses_per_quarter_note
            float time_beats_scale             = 1f / midi_data.header.time_division;
            float time_beats_to_measures_scale = 1f / beats_per_measure;

            // Instatiate the event list
            pEvents = new List <MIDIEventHelper>();
            // Starting from time zero
            float time_beats    = 0f;
            float time_measures = 0f;

            // Keep track of the last note-on events and
            // match them with note-off events that follow,
            // then store the time between the events as
            // the duration in the event helper
            MIDIEventHelper[] notes_on_last = new MIDIEventHelper[256];
            // Keep track of the valid event index
            int index = 0;
            // Add all of the events needed for this track to the backing list (pEvents)
            MIDIEventHelper previous_helper = null;
            var             track_filtered  = track.events.Where(MIDIEventListFilter);

            foreach (var midi_event in track_filtered)
            {
                if (filter.Accepts(midi_event))
                {
                    // Calculate the event time based on delta_time
                    // delta_time is measured in ticks
                    float delta_time = (float)midi_event.delta_time;
                    time_beats += time_beats_scale * delta_time;
                    // Quantize to 32nd notes
                    time_beats     = Quantize(time_beats, 32);
                    time_measures += time_beats_to_measures_scale * time_beats;

                    // Create an event helper (wrapper for event and details)
                    MIDIEventHelper current_event_helper = new MIDIEventHelper()
                    {
                        MIDIEvent     = midi_event,
                        Index         = index,
                        TimeBeats     = time_beats,
                        TimeMeasures  = time_measures,
                        DurationBeats = 0f,
                    };
                    // Add the event helper to the backing list
                    pEvents.Add(current_event_helper);
                    // If this event is a note off event
                    if (midi_event is NoteOffEvent)
                    {
                        var note_off        = midi_event as NoteOffEvent;
                        int number          = note_off.note_number;
                        var on_event_helper = notes_on_last[number];
                        if (on_event_helper != null)
                        {
                            float duration = time_beats - on_event_helper.TimeBeats;
                            on_event_helper.DurationBeats      = duration;
                            current_event_helper.DurationBeats = duration;
                        }
                        // The note off event is not accounted for when consolidating
                    }
                    //  If this event is a note on event
                    else if (midi_event is NoteOnEvent)
                    {
                        // Store it as the last note-on event for this note number
                        var note_on = midi_event as NoteOnEvent;
                        int number  = note_on.note_number;
                        notes_on_last[number] = current_event_helper;
                    }
                    index++;
                    previous_helper = current_event_helper;
                }
                else if (MIDIEventFilter.TrackNameFilter.Accepts(midi_event))
                {
                    Name = track.chunk_ID ?? "";

                    // TODO: get this working
                    //var name = (m_e.Element as Midi.Events.MetaEvents.SequenceOrTrackNameEvent).name;
                    // Small workaround for bug in MIDI parsing library
                    //Name = name.Trim(new[] {'\0'});
                }
            }
        }