Ejemplo n.º 1
0
 protected virtual void OnEvent(SmfEvent m)
 {
     if (EventReceived != null)
     {
         EventReceived(m);
     }
 }
Ejemplo n.º 2
0
        SmfMessage ReadMessage(int deltaTime)
        {
            byte b = PeekByte();

            running_status = b < 0x80 ? running_status : ReadByte();
            int len;

            switch (running_status)
            {
            case SmfEvent.SysEx1:
            case SmfEvent.SysEx2:
            case SmfEvent.Meta:
                byte metaType = running_status == SmfEvent.Meta ? ReadByte() : (byte)0;
                len = ReadVariableLength();
                byte [] args = new byte [len];
                if (len > 0)
                {
                    ReadBytes(args);
                }
                return(new SmfMessage(deltaTime, new SmfEvent(running_status, metaType, 0, args)));

            default:
                int value = running_status;
                value += ReadByte() << 8;
                if (SmfEvent.FixedDataSize(running_status) == 2)
                {
                    value += ReadByte() << 16;
                }
                return(new SmfMessage(deltaTime, new SmfEvent(value)));
            }
        }
Ejemplo n.º 3
0
 public virtual void ProcessEvent(SmfEvent evt)
 {
     switch (evt.EventType) {
     case SmfEvent.NoteOn:
         Channels [evt.Channel].NoteVelocity [evt.Msb] = evt.Lsb;
         break;
     case SmfEvent.NoteOff:
         Channels [evt.Channel].NoteVelocity [evt.Msb] = 0;
         break;
     case SmfEvent.PAf:
         Channels [evt.Channel].PAfVelocity [evt.Msb] = evt.Lsb;
         break;
     case SmfEvent.CC:
         // FIXME: handle RPNs and NRPNs by DTE
         switch (evt.Msb) {
         case SmfCC.NrpnMsb:
         case SmfCC.NrpnLsb:
             Channels [evt.Channel].DteTarget = DteTarget.Nrpn;
             break;
         case SmfCC.RpnMsb:
         case SmfCC.RpnLsb:
             Channels [evt.Channel].DteTarget = DteTarget.Rpn;
             break;
         case SmfCC.DteMsb:
             Channels [evt.Channel].ProcessDte (evt.Lsb, true);
             break;
         case SmfCC.DteLsb:
             Channels [evt.Channel].ProcessDte (evt.Lsb, false);
             break;
         case SmfCC.DteIncrement:
             Channels [evt.Channel].ProcessDteIncrement ();
             break;
         case SmfCC.DteDecrement:
             Channels [evt.Channel].ProcessDteDecrement ();
             break;
         }
         Channels [evt.Channel].Controls [evt.Msb] = evt.Lsb;
         break;
     case SmfEvent.Program:
         Channels [evt.Channel].Program = evt.Msb;
         break;
     case SmfEvent.CAf:
         Channels [evt.Channel].CAf = evt.Msb;
         break;
     case SmfEvent.Pitch:
         Channels [evt.Channel].PitchBend = (short) ((evt.Msb << 7) + evt.Lsb);
         break;
     }
     if (EventReceived != null)
         EventReceived (evt);
 }
Ejemplo n.º 4
0
        public MidiPlayer(SmfMusic 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 SmfEvent.SysEx1:
                case SmfEvent.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.SendAsync(buffer, 0, m.Data.Length + 1, 0);
                    break;

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

                default:
                    var size = SmfEvent.FixedDataSize(m.StatusByte);
                    buffer [0] = m.StatusByte;
                    buffer [1] = m.Msb;
                    buffer [2] = m.Lsb;
                    output.SendAsync(buffer, 0, size + 1, 0);
                    break;
                }
            };
        }
Ejemplo n.º 5
0
        public void WriteTrack(SmfTrack track)
        {
            stream.Write(Encoding.UTF8.GetBytes("MTrk"), 0, 4);
            WriteInt(GetTrackDataSize(track));

            byte running_status = 0;

            foreach (SmfMessage e in track.Messages)
            {
                Write7BitVariableInteger(e.DeltaTime);
                switch (e.Event.EventType)
                {
                case SmfEvent.Meta:
                    meta_event_writer(false, e, stream);
                    break;

                case SmfEvent.SysEx1:
                case SmfEvent.SysEx2:
                    stream.WriteByte(e.Event.EventType);
                    Write7BitVariableInteger(e.Event.Data.Length);
                    stream.Write(e.Event.Data, 0, e.Event.Data.Length);
                    break;

                default:
                    if (DisableRunningStatus || e.Event.StatusByte != running_status)
                    {
                        stream.WriteByte(e.Event.StatusByte);
                    }
                    int len = SmfEvent.FixedDataSize(e.Event.EventType);
                    stream.WriteByte(e.Event.Msb);
                    if (len > 1)
                    {
                        stream.WriteByte(e.Event.Lsb);
                    }
                    if (len > 2)
                    {
                        throw new Exception("Unexpected data size: " + len);
                    }
                    break;
                }
                running_status = e.Event.StatusByte;
            }
        }
Ejemplo n.º 6
0
 SmfTrack GenerateTrack(MmlResolvedTrack source)
 {
     var rtrk = new SmfTrack ();
     int cur = 0;
     foreach (var ev in source.Events) {
         SmfEvent evt;
         if (ev.Arguments.Count == 3)
             evt = new SmfEvent (ev.Arguments [0], ev.Arguments [1], ev.Arguments [2], null);
         else if (ev.Arguments [0] == 0xFF)
             evt = new SmfEvent (ev.Arguments [0], ev.Arguments [1], 0, ev.Arguments.Skip (2).ToArray ());
         else
             evt = new SmfEvent (ev.Arguments [0], 0, 0, ev.Arguments.Skip (1).ToArray ());
         var msg = new SmfMessage (ev.Tick - cur, evt);
         rtrk.Messages.Add (msg);
         cur = ev.Tick;
     }
     rtrk.Messages.Add (new SmfMessage (0, new SmfEvent (0xFF, 0x2F, 0, new byte [0])));
     return rtrk;
 }
Ejemplo n.º 7
0
        int GetTrackDataSize(SmfTrack track)
        {
            int  size           = 0;
            byte running_status = 0;

            foreach (SmfMessage e in track.Messages)
            {
                // delta time
                size += GetVariantLength(e.DeltaTime);

                // arguments
                switch (e.Event.EventType)
                {
                case SmfEvent.Meta:
                    size += meta_event_writer(true, e, null);
                    break;

                case SmfEvent.SysEx1:
                case SmfEvent.SysEx2:
                    size++;
                    size += GetVariantLength(e.Event.Data.Length);
                    size += e.Event.Data.Length;
                    break;

                default:
                    // message type & channel
                    if (DisableRunningStatus || running_status != e.Event.StatusByte)
                    {
                        size++;
                    }
                    size += SmfEvent.FixedDataSize(e.Event.EventType);
                    break;
                }

                running_status = e.Event.StatusByte;
            }
            return(size);
        }
Ejemplo n.º 8
0
 public SmfMessage(int deltaTime, SmfEvent evt)
 {
     DeltaTime = deltaTime;
     Event = evt;
 }
Ejemplo n.º 9
0
 public void AddEvent(int deltaInsertAt, SmfEvent e)
 {
     e = new SmfEvent (deltaInsertAt - TotalDeltaTime, e.Message);
     Track.Events.Add (e);
     TotalDeltaTime = deltaInsertAt;
 }
Ejemplo n.º 10
0
 // Override it to customize track dispatcher. It would be
 // useful to split note messages out from non-note ones,
 // to ease data reading.
 public virtual int GetTrackID(SmfEvent e)
 {
     switch (e.Message.MessageType) {
     case SmfMessage.Meta:
     case SmfMessage.SysEx1:
     case SmfMessage.SysEx2:
         return -1;
     default:
         return e.Message.Channel;
     }
 }
Ejemplo n.º 11
0
        // FIXME: it should rather be implemented to iterate all
        // tracks with index to events, 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.
        SmfMusic GetMergedEvents()
        {
            IList<SmfEvent> l = new List<SmfEvent> ();

            foreach (var track in source.Tracks) {
                int delta = 0;
                foreach (var mev in track.Events) {
                    delta += mev.DeltaTime;
                    l.Add (new SmfEvent (delta, mev.Message));
                }
            }

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

            // Sort() does not always 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 ieeue, 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<SmfEvent> (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]);
            //if (l.Count != l2.Count) throw new Exception (String.Format ("Internal eror: count mismatch: l1 {0} l2 {1}", l.Count, l2.Count));
            l = l2;

            // now events should be sorted correctly.

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

            var m = new SmfMusic ();
            m.DeltaTimeSpec = source.DeltaTimeSpec;
            m.Format = 0;
            m.Tracks.Add (new SmfTrack (l));
            return m;
        }
Ejemplo n.º 12
0
 public void AddEvent(SmfEvent evt)
 {
     events.Add (evt);
 }
Ejemplo n.º 13
0
        public virtual void HandleEvent(SmfEvent e)
        {
            if (e.DeltaTime != 0) {
                var ms = GetDeltaTimeInMilliseconds (e.DeltaTime);
                Thread.Sleep (ms);
            }
            if (e.Message.StatusByte == 0xFF && e.Message.Msb == SmfMetaType.Tempo)
                current_tempo = SmfMetaType.GetTempo (e.Message.Data);

            OnMessage (e.Message);
            PlayDeltaTime += e.DeltaTime;
        }
Ejemplo n.º 14
0
 public SmfMessage(int deltaTime, SmfEvent evt)
 {
     DeltaTime = deltaTime;
     Event     = evt;
 }
Ejemplo n.º 15
0
        public virtual void ProcessEvent(SmfEvent evt)
        {
            switch (evt.EventType)
            {
            case SmfEvent.NoteOn:
                Channels [evt.Channel].NoteVelocity [evt.Msb] = evt.Lsb;
                break;

            case SmfEvent.NoteOff:
                Channels [evt.Channel].NoteVelocity [evt.Msb] = 0;
                break;

            case SmfEvent.PAf:
                Channels [evt.Channel].PAfVelocity [evt.Msb] = evt.Lsb;
                break;

            case SmfEvent.CC:
                // FIXME: handle RPNs and NRPNs by DTE
                switch (evt.Msb)
                {
                case SmfCC.NrpnMsb:
                case SmfCC.NrpnLsb:
                    Channels [evt.Channel].DteTarget = DteTarget.Nrpn;
                    break;

                case SmfCC.RpnMsb:
                case SmfCC.RpnLsb:
                    Channels [evt.Channel].DteTarget = DteTarget.Rpn;
                    break;

                case SmfCC.DteMsb:
                    Channels [evt.Channel].ProcessDte(evt.Lsb, true);
                    break;

                case SmfCC.DteLsb:
                    Channels [evt.Channel].ProcessDte(evt.Lsb, false);
                    break;

                case SmfCC.DteIncrement:
                    Channels [evt.Channel].ProcessDteIncrement();
                    break;

                case SmfCC.DteDecrement:
                    Channels [evt.Channel].ProcessDteDecrement();
                    break;
                }
                Channels [evt.Channel].Controls [evt.Msb] = evt.Lsb;
                break;

            case SmfEvent.Program:
                Channels [evt.Channel].Program = evt.Msb;
                break;

            case SmfEvent.CAf:
                Channels [evt.Channel].CAf = evt.Msb;
                break;

            case SmfEvent.Pitch:
                Channels [evt.Channel].PitchBend = (short)((evt.Msb << 7) + evt.Lsb);
                break;
            }
            if (EventReceived != null)
            {
                EventReceived(evt);
            }
        }
Ejemplo n.º 16
0
 protected virtual void OnEvent(SmfEvent m)
 {
     if (EventReceived != null)
         EventReceived (m);
 }