Exemplo n.º 1
0
        private void AddMIDICommand(MIDICommandType type, int channel, int note, int velocity)
        {
            // Each of the three MIDI commands supported by VRChat is composed of three bytes.
            // The first four bits of the first byte determine the command type (NoteOn/NoteOff/ControlChange).
            // The last four bits of the first byte determine the channel (instrument) the command is targeting.
            // The second byte's 7 primary bits determine the note to be played.
            // The last byte's 7 primary bits detemrine the velocity of the command.

            if (currentOffset > buffer.Length - MIDI_BYTES_PER_COMMAND)
            {
                throw new InvalidOperationException("MIDICommandChunk is full");
            }

            switch (type)
            {
            case MIDICommandType.NoteOff:
                buffer[currentOffset] = 0x80;
                break;

            case MIDICommandType.NoteOn:
                buffer[currentOffset] = 0x90;
                break;

            case MIDICommandType.ControlChange:
                buffer[currentOffset] = 0xB0;
                break;
            }
            buffer[currentOffset++] |= (byte)channel;
            buffer[currentOffset++]  = (byte)note;
            buffer[currentOffset++]  = (byte)velocity;
        }
Exemplo n.º 2
0
        private void Add(byte a, byte b, int extraBits = 0, MIDICommandType type = MIDICommandType.NoteOn)
        {
            // Since MIDI commands' note and velocity bytes only have 7 usable bits,
            // the highest bits of each two bytes are moved into the lowest two bits
            // of the MIDI channel.
            int channelA    = (a & 0x80) >> 7;
            int channelB    = (b & 0x80) >> 6;
            int channelHigh = (extraBits & 0x3) << 2;
            int channel     = channelHigh | channelA | channelB;

            AddMIDICommand(type, channel, a & 0x7F, b & 0x7F);
        }