Пример #1
0
 // util functions
 private static bool TrackIsOmitable(MidiTrack tr)
 {
     foreach (MidiEvent ev in tr.midiEvents)
     {
         if (ev is MetaMidiEvent)
         {
             MetaMidiEvent mev = ev as MetaMidiEvent;
             if (mev.getMetaType() == MetaType.TempoSetting)
             {
                 return(false);
             }
             else if (mev.getMetaType() == MetaType.TimeSignature)
             {
                 return(false);
             }
             else if (mev.getMetaType() == MetaType.MarkerText)
             {
                 return(false);
             }
         }
         else if (ev is MessageMidiEvent)
         {
             MessageMidiEvent mev = ev as MessageMidiEvent;
             if (mev.type == NormalType.NoteON)
             {
                 return(false);
             }
             if (mev.type == NormalType.NoteOFF)
             {
                 return(false);
             }
         }
     }
     return(true);
 }
Пример #2
0
 public static void QuantizeTempo(MidiFile midi)
 {
     /******************
      * Rounds Tempo Events to the nearest BPM integer
      */
     foreach (MidiTrack trk in midi.midiTracks)
     {
         for (int i = 0; i < trk.midiEvents.Count; i++)
         {
             MidiEvent ev = trk.midiEvents[i];
             if (ev is MetaMidiEvent)
             {
                 MetaMidiEvent mev = ev as MetaMidiEvent;
                 if (mev.getMetaType() == MetaType.TempoSetting)
                 {
                     byte[] tempoBytes = mev.getEventData();
                     Debug.Assert(tempoBytes.Length == 6);
                     int    us            = (tempoBytes[3] << 16) | (tempoBytes[4] << 8) | tempoBytes[5];
                     double bpm           = CalcBPM(us);
                     double ibpm          = Math.Round(bpm, MidpointRounding.AwayFromZero);
                     int    ius           = CalcUsPerBeat(ibpm);
                     byte[] newTempoBytes = new byte[3];
                     newTempoBytes[0] = (byte)(ius >> 16);
                     newTempoBytes[1] = (byte)((ius >> 8) & 0xFF);
                     newTempoBytes[2] = (byte)(ius & 0xFF);
                     MetaMidiEvent newTempoEvent = new MetaMidiEvent(mev.absoluteTicks, 0x51, newTempoBytes);
                     trk.midiEvents[i] = newTempoEvent;
                 }
             }
         }
     }
 }
Пример #3
0
        public static void Trim(MidiFile midi)
        {
            /******************
             *  removes empty tracks and redundant controller/voice events
             */
            midi.midiTracks.RemoveAll(TrackIsOmitable);
            foreach (MidiTrack tr in midi.midiTracks)
            {
                // int array for storing the last set values of the controller values
                int[] controllerValues = new int[128];
                for (int i = 0; i < controllerValues.Length; i++)
                {
                    controllerValues[i] = -1;
                }
                int lastVoice      = -1;
                int lastPitchBendA = -1;
                int lastPitchBendB = -1;
                int lastTempo      = -1;

                for (int i = 0; i < tr.midiEvents.Count;)
                {
                    if (tr.midiEvents[i] is MessageMidiEvent)
                    {
                        MessageMidiEvent mev = tr.midiEvents[i] as MessageMidiEvent;
                        if (mev.type == NormalType.Program)
                        {
                            if (mev.parameter1 == lastVoice)
                            {
                                tr.midiEvents.RemoveAt(i);
                                continue;
                            }
                            lastVoice = mev.parameter1;
                        }
                        else if (mev.type == NormalType.PitchBend)
                        {
                            if (mev.parameter1 == lastPitchBendA && mev.parameter2 == lastPitchBendB)
                            {
                                tr.midiEvents.RemoveAt(i);
                                continue;
                            }
                            lastPitchBendA = mev.parameter1;
                            lastPitchBendB = mev.parameter2;
                        }
                        else if (mev.type == NormalType.Controller)
                        {
                            if (controllerValues[mev.parameter1] == mev.parameter2)
                            {
                                tr.midiEvents.RemoveAt(i);
                                continue;
                            }
                            controllerValues[mev.parameter1] = mev.parameter2;
                        }
                    }
                    else if (tr.midiEvents[i] is MetaMidiEvent)
                    {
                        MetaMidiEvent mev = tr.midiEvents[i] as MetaMidiEvent;
                        if (mev.getMetaType() == MetaType.TempoSetting)
                        {
                            byte[] tempoBytes = mev.getEventData();
                            Debug.Assert(tempoBytes.Length == 6);
                            int us = (tempoBytes[3] << 16) | (tempoBytes[4] << 8) | tempoBytes[5];

                            if (lastTempo == us)
                            {
                                tr.midiEvents.RemoveAt(i);
                                continue;
                            }
                            lastTempo = us;
                        }
                    }
                    // only count up if the current event didn't get deleted
                    i++;
                }
            }
        }