Esempio n. 1
0
 public void WriteMusic(MidiMusic music)
 {
     WriteHeader(music.Format, (short)music.Tracks.Count, music.DeltaTimeSpec);
     foreach (var track in music.Tracks)
     {
         WriteTrack(track);
     }
 }
Esempio n. 2
0
 public void Read(Stream stream)
 {
     this.stream = stream;
     data        = new MidiMusic();
     try {
         DoParse();
     } finally {
         this.stream = null;
     }
 }
Esempio n. 3
0
        public MidiPlayer(MidiMusic music, IMidiOutput output, IMidiTimeManager timeManager)
        {
            if (music == null)
            {
                throw new ArgumentNullException("music");
            }
            if (output == null)
            {
                throw new ArgumentNullException("output");
            }
            if (timeManager == null)
            {
                throw new ArgumentNullException("timeManager");
            }

            this.output = output;

            player         = new MidiSyncPlayer(music, timeManager);
            EventReceived += (m) => {
                switch (m.EventType)
                {
                case MidiEvent.NoteOn:
                case MidiEvent.NoteOff:
                    if (channel_mask != null && channel_mask [m.Channel])
                    {
                        return;                         // ignore messages for the masked channel.
                    }
                    goto default;

                case MidiEvent.SysEx1:
                case MidiEvent.SysEx2:
                    if (buffer.Length <= m.Data.Length)
                    {
                        buffer = new byte [buffer.Length * 2];
                    }
                    buffer [0] = m.StatusByte;
                    Array.Copy(m.Data, 0, buffer, 1, m.Data.Length);
                    output.Send(buffer, 0, m.Data.Length + 1, 0);
                    break;

                case MidiEvent.Meta:
                    // do nothing.
                    break;

                default:
                    var size = MidiEvent.FixedDataSize(m.StatusByte);
                    buffer [0] = m.StatusByte;
                    buffer [1] = m.Msb;
                    buffer [2] = m.Lsb;
                    output.Send(buffer, 0, size + 1, 0);
                    break;
                }
            };
        }
Esempio n. 4
0
        public MidiSyncPlayer(MidiMusic music, IMidiTimeManager timeManager)
        {
            if (music == null)
            {
                throw new ArgumentNullException("music");
            }
            time_manager = timeManager;

            this.music = music;
            messages   = SmfTrackMerger.Merge(music).Tracks [0].Messages;
            state      = PlayerState.Stopped;
        }
Esempio n. 5
0
 public void Read(Stream stream)
 {
     if (stream == null)
     {
         throw new ArgumentNullException(nameof(stream));
     }
     this.stream = stream;
     data        = new MidiMusic();
     try {
         DoParse();
     } finally {
         this.stream = null;
     }
 }
        public MidiMusic Split()
        {
            int totalDeltaTime = 0;

            foreach (var e in source)
            {
                totalDeltaTime += e.DeltaTime;
                int id = GetTrackID(e);
                GetTrack(id).AddMessage(totalDeltaTime, e);
            }

            var m = new MidiMusic();

            m.DeltaTimeSpec = delta_time_spec;
            foreach (var t in tracks.Values)
            {
                m.Tracks.Add(t.Track);
            }
            return(m);
        }
Esempio n. 7
0
        public MidiPlayer(MidiMusic music, IMidiOutput output, IMidiPlayerTimeManager timeManager)
        {
            if (music == null)
            {
                throw new ArgumentNullException("music");
            }
            if (output == null)
            {
                throw new ArgumentNullException("output");
            }
            if (timeManager == null)
            {
                throw new ArgumentNullException("timeManager");
            }

            this.music  = music;
            this.output = output;

            messages         = SmfTrackMerger.Merge(music).Tracks [0].Messages;
            player           = new MidiEventLooper(messages, timeManager, music.DeltaTimeSpec);
            player.Starting += () => {
                // all control reset on all channels.
                for (int i = 0; i < 16; i++)
                {
                    buffer [0] = (byte)(i + 0xB0);
                    buffer [1] = 0x79;
                    buffer [2] = 0;
                    output.Send(buffer, 0, 3, 0);
                }
            };
            EventReceived += (m) => {
                switch (m.EventType)
                {
                case MidiEvent.NoteOn:
                case MidiEvent.NoteOff:
                    if (channel_mask != null && channel_mask [m.Channel])
                    {
                        return;                         // ignore messages for the masked channel.
                    }
                    goto default;

                case MidiEvent.SysEx1:
                case MidiEvent.SysEx2:
                    if (buffer.Length <= m.Data.Length)
                    {
                        buffer = new byte [buffer.Length * 2];
                    }
                    buffer [0] = m.StatusByte;
                    Array.Copy(m.Data, 0, buffer, 1, m.Data.Length);
                    output.Send(buffer, 0, m.Data.Length + 1, 0);
                    break;

                case MidiEvent.Meta:
                    // do nothing.
                    break;

                default:
                    var size = MidiEvent.FixedDataSize(m.StatusByte);
                    buffer [0] = m.StatusByte;
                    buffer [1] = m.Msb;
                    buffer [2] = m.Lsb;
                    output.Send(buffer, 0, size + 1, 0);
                    break;
                }
            };
        }
Esempio n. 8
0
 public static MidiMusic Merge(MidiMusic source)
 {
     return(new SmfTrackMerger(source).GetMergedMessages());
 }
Esempio n. 9
0
 public MidiPlayer(MidiMusic music, IMidiPlayerTimeManager timeManager)
     : this(music, MidiAccessManager.Empty, timeManager)
 {
 }
Esempio n. 10
0
 public MidiPlayer(MidiMusic music, IMidiAccess access, IMidiPlayerTimeManager timeManager)
     : this(music, access.OpenOutputAsync(access.Outputs.First().Id).Result, timeManager)
 {
     should_dispose_output = true;
 }
Esempio n. 11
0
 public MidiPlayer(MidiMusic music, IMidiAccess access)
     : this(music, access, new SimpleAdjustingMidiPlayerTimeManager())
 {
 }
Esempio n. 12
0
 public MidiPlayer(MidiMusic music, IMidiOutput output)
     : this(music, output, new SimpleAdjustingMidiPlayerTimeManager())
 {
 }
Esempio n. 13
0
 public MidiPlayer(MidiMusic music)
     : this(music, MidiAccessManager.Empty)
 {
 }
Esempio n. 14
0
 SmfTrackMerger(MidiMusic source)
 {
     this.source = source;
 }
Esempio n. 15
0
 public MidiSyncPlayer(MidiMusic music)
     : this(music, new SimpleMidiTimeManager())
 {
 }
Esempio n. 16
0
 public int GetTotalPlayTimeMilliseconds()
 {
     return(MidiMusic.GetTotalPlayTimeMilliseconds(messages, music.DeltaTimeSpec));
 }
Esempio n. 17
0
        // FIXME: it should rather be implemented to iterate all
        // tracks with index to messages, pick the track which contains
        // the nearest event and push the events into the merged queue.
        // It's simpler, and costs less by removing sort operation
        // over thousands of events.
        MidiMusic GetMergedMessages()
        {
            if (source.Format == 0)
            {
                return(source);
            }

            IList <MidiMessage> l = new List <MidiMessage> ();

            foreach (var track in source.Tracks)
            {
                int delta = 0;
                foreach (var mev in track.Messages)
                {
                    delta += mev.DeltaTime;
                    l.Add(new MidiMessage(delta, mev.Event));
                }
            }

            if (l.Count == 0)
            {
                return new MidiMusic()
                       {
                           DeltaTimeSpec = source.DeltaTimeSpec
                       }
            }
            ;                                                                                     // empty (why did you need to sort your song file?)

            // Usual Sort() over simple list of MIDI events does not work as expected.
            // For example, it does not always preserve event
            // orders on the same channels when the delta time
            // of event B after event A is 0. It could be sorted
            // either as A->B or B->A.
            //
            // To resolve this issue, we have to sort "chunk"
            // of events, not all single events themselves, so
            // that order of events in the same chunk is preserved
            // i.e. [AB] at 48 and [CDE] at 0 should be sorted as
            // [CDE] [AB].

            var idxl = new List <int> (l.Count);

            idxl.Add(0);
            int prev = 0;

            for (int i = 0; i < l.Count; i++)
            {
                if (l [i].DeltaTime != prev)
                {
                    idxl.Add(i);
                    prev = l [i].DeltaTime;
                }
            }

            idxl.Sort(delegate(int i1, int i2) {
                return(l [i1].DeltaTime - l [i2].DeltaTime);
            });

            // now build a new event list based on the sorted blocks.
            var l2 = new List <MidiMessage> (l.Count);
            int idx;

            for (int i = 0; i < idxl.Count; i++)
            {
                for (idx = idxl [i], prev = l [idx].DeltaTime; idx < l.Count && l [idx].DeltaTime == prev; idx++)
                {
                    l2.Add(l [idx]);
                }
            }
            l = l2;

            // now messages should be sorted correctly.

            var waitToNext = l [0].DeltaTime;

            for (int i = 0; i < l.Count - 1; i++)
            {
                if (l [i].Event.Value != 0)                   // if non-dummy
                {
                    var tmp = l [i + 1].DeltaTime - l [i].DeltaTime;
                    l [i]      = new MidiMessage(waitToNext, l [i].Event);
                    waitToNext = tmp;
                }
            }
            l [l.Count - 1] = new MidiMessage(waitToNext, l [l.Count - 1].Event);

            var m = new MidiMusic();

            m.DeltaTimeSpec = source.DeltaTimeSpec;
            m.Format        = 0;
            m.Tracks.Add(new MidiTrack(l));
            return(m);
        }
    }