コード例 #1
0
ファイル: MidiSequence.cs プロジェクト: None-later/MidiSlicer
        /// <summary>
        /// Stretches or compresses the MIDI sequence events
        /// </summary>
        /// <remarks>If <paramref name="adjustTempo"/> is false this will change the playback speed of the MIDI</remarks>
        /// <param name="diff">The differential for the size. 1 is the same length, .5 would be half the length and 2 would be twice the length</param>
        /// <param name="adjustTempo">Indicates whether or not the tempo should be adjusted to compensate</param>
        /// <returns>A new MIDI sequence that is stretched the specified amount</returns>
        public MidiSequence Stretch(double diff, bool adjustTempo = false)
        {
            var result = new MidiSequence();

            if (!adjustTempo)
            {
                foreach (var e in Events)
                {
                    result.Events.Add(new MidiEvent((int)Math.Round(e.Position * diff, MidpointRounding.AwayFromZero), e.Message));
                }
            }
            else
            {
                byte runningStatus = 0;
                foreach (var e in Events)
                {
                    if (0 != e.Message.Status)
                    {
                        runningStatus = e.Message.Status;
                    }
                    var m = e.Message;
                    if (-1 == m.PayloadLength)
                    {
                        if (0xFF == runningStatus)
                        {
                            var mbs = m as MidiMessageMeta;
                            if (0x51 == mbs.Data1)
                            {
                                var mt = 0;
                                if (BitConverter.IsLittleEndian)
                                {
                                    mt = (mbs.Data[0] << 16) | (mbs.Data[1] << 8) | mbs.Data[2];
                                }
                                else
                                {
                                    mt = (mbs.Data[2] << 16) | (mbs.Data[1] << 8) | mbs.Data[0];
                                }
                                mt = (int)Math.Round(mt / diff, MidpointRounding.AwayFromZero);
                                var buf = new byte[3];
                                if (BitConverter.IsLittleEndian)
                                {
                                    buf[0] = unchecked ((byte)((mt >> 16) & 0xFF));
                                    buf[1] = unchecked ((byte)((mt >> 8) & 0xFF));
                                    buf[2] = unchecked ((byte)((mt) & 0xFF));
                                }
                                else
                                {
                                    buf[0] = unchecked ((byte)((mt) & 0xFF));
                                    buf[1] = unchecked ((byte)((mt >> 8) & 0xFF));
                                    buf[2] = unchecked ((byte)((mt >> 16) & 0xFF));
                                }
                                m = new MidiMessageMeta(mbs.Status, mbs.Data1, buf);
                            }
                        }
                    }
                    result.Events.Add(new MidiEvent((int)Math.Round(e.Position * diff, MidpointRounding.AwayFromZero), m));
                }
            }
            return(result);
        }
コード例 #2
0
ファイル: MidiSequence.cs プロジェクト: None-later/MidiSlicer
        internal static MidiSequence ReadFrom(Stream stream)
        {
            MidiSequence result = new MidiSequence();
            var          rs     = (byte)0;
            var          delta  = _ReadVarlen(stream);

            if (BitConverter.IsLittleEndian)
            {
                delta = _Swap(delta);
            }
            var i = stream.ReadByte();

            while (-1 != i)
            {
                var hasStatus = false;
                var b         = (byte)i;
                if (0x7F < b)
                {
                    hasStatus = true;
                    rs        = b;
                    i         = stream.ReadByte();
                    if (-1 != i)
                    {
                        b = (byte)i;
                    }
                    else
                    {
                        b = 0;
                    }
                }
                var st = hasStatus ? rs : (byte)0;
                var m  = (MidiMessage)null;
                switch (rs & 0xF0)
                {
                case 0x80:
                    if (i == -1)
                    {
                        throw new EndOfStreamException();
                    }
                    m = new MidiMessageNoteOff(b, (byte)stream.ReadByte(), unchecked ((byte)(st & 0x0F)));
                    break;

                case 0x90:
                    if (i == -1)
                    {
                        throw new EndOfStreamException();
                    }
                    m = new MidiMessageNoteOn(b, (byte)stream.ReadByte(), unchecked ((byte)(st & 0x0F)));
                    break;

                case 0xA0:
                    if (i == -1)
                    {
                        throw new EndOfStreamException();
                    }
                    m = new MidiMessageKeyPressure(b, (byte)stream.ReadByte(), unchecked ((byte)(st & 0x0F)));
                    break;

                case 0xB0:
                    if (i == -1)
                    {
                        throw new EndOfStreamException();
                    }
                    m = new MidiMessageCC(b, (byte)stream.ReadByte(), unchecked ((byte)(st & 0x0F)));
                    break;

                case 0xC0:
                    if (i == -1)
                    {
                        throw new EndOfStreamException();
                    }
                    m = new MidiMessagePatchChange(b, unchecked ((byte)(st & 0x0F)));
                    break;

                case 0xD0:
                    if (i == -1)
                    {
                        throw new EndOfStreamException();
                    }
                    m = new MidiMessageChannelPressure(b, unchecked ((byte)(st & 0x0F)));
                    break;

                case 0xE0:
                    if (i == -1)
                    {
                        throw new EndOfStreamException();
                    }
                    m = new MidiMessageChannelPitch(b, (byte)stream.ReadByte(), unchecked ((byte)(st & 0x0F)));
                    break;

                case 0xF0:
                    switch (rs & 0xF)
                    {
                    case 0xF:
                        if (i == -1)
                        {
                            throw new EndOfStreamException();
                        }
                        var l = _ReadVarlen(stream);
                        //if (BitConverter.IsLittleEndian)
                        //	l = _Swap(l);
                        var ba = new byte[l];
                        if (l != stream.Read(ba, 0, ba.Length))
                        {
                            throw new EndOfStreamException();
                        }
                        m = new MidiMessageMeta(st, b, ba);
                        break;

                    case 0x0:
                    case 0x7:
                        if (i == -1)
                        {
                            throw new EndOfStreamException();
                        }
                        l = _ReadVarlen(b, stream);
                        //if (BitConverter.IsLittleEndian)
                        //	l = _Swap(l);
                        ba = new byte[l];
                        if (l != stream.Read(ba, 0, ba.Length))
                        {
                            throw new EndOfStreamException();
                        }
                        m = new MidiMessageSysex(st, ba);
                        break;

                    case 0x2:
                        if (i == -1)
                        {
                            throw new EndOfStreamException();
                        }
                        m = new MidiMessageWord(st, b, (byte)stream.ReadByte());
                        break;

                    case 0x3:
                        if (i == -1)
                        {
                            throw new EndOfStreamException();
                        }
                        m = new MidiMessageByte(st, b);
                        break;

                    case 0x6:

                    case 0x8:
                    case 0xA:
                    case 0xB:
                    case 0xC:
                        // status *was* specified if we got here
                        m = new MidiMessage(st);
                        break;

                    default:
                        throw new NotSupportedException("The MIDI message is not recognized.");
                    }
                    break;
                }

                result.Events.Add(new MidiEvent(delta, m));
                i = _ReadVarlen(stream);
                if (-1 == i)
                {
                    break;
                }
                delta = i;
                i     = stream.ReadByte();
            }
            return(result);
        }