示例#1
0
        private void UnpackVoicePacket(byte[] packet, int type)
        {
            var vType  = (SpeechCodecs)type;
            var target = (SpeechTarget)(packet[0] & 0x1F);

            using (var reader = new UdpPacketReader(new MemoryStream(packet, 1, packet.Length - 1)))
            {
                UInt32 session  = (uint)reader.ReadVarInt64();
                Int64  sequence = reader.ReadVarInt64();

                //Null codec means the user was not found. This can happen if a user leaves while voice packets are still in flight
                IVoiceCodec codec = Protocol.GetCodec(session, vType);
                if (codec == null)
                {
                    return;
                }

                if (vType == SpeechCodecs.Opus)
                {
                    int size = (int)reader.ReadVarInt64();
                    size &= 0x1fff;

                    if (size == 0)
                    {
                        return;
                    }

                    byte[] data = reader.ReadBytes(size);
                    if (data == null)
                    {
                        return;
                    }

                    Protocol.EncodedVoice(data, session, sequence, codec, target);
                }
                else
                {
                    throw new NotImplementedException("Codec is not opus");

                    //byte header;
                    //do
                    //{
                    //    header = reader.ReadByte();
                    //    int length = header & 0x7F;
                    //    if (length > 0)
                    //    {
                    //        byte[] data = reader.ReadBytes(length);
                    //        if (data == null)
                    //            break;

                    //        //TODO: Put *encoded* packets into a queue, then decode the head of the queue
                    //        //TODO: This allows packets to come into late and be inserted into the correct place in the queue (if they arrive before decoding handles a later packet)
                    //        byte[] decodedPcmData = codec.Decode(data);
                    //        if (decodedPcmData != null)
                    //            Protocol.Voice(decodedPcmData, session, sequence);
                    //    }

                    //} while ((header & 0x80) > 0);
                }
            }
        }
        private void Voice(byte[] packet)
        {
            //This is all horrible!
            //TODO: Move all the decoding related rubbish to within the MumbleConnection (internal void ReceivedEncryptedUdp(byte[] packet) Line 78)
            //This should just receive ordered blocks of decoded PCM data

            int type = packet[0] >> 5 & 0x7;
            int flags = packet[0] & 0x1f;

            if (type != (int)SpeechCodecs.CeltAlpha && type != (int)SpeechCodecs.CeltBeta && type != (int)SpeechCodecs.Speex)
                return;

            using (var reader = new UdpPacketReader(new MemoryStream(packet, 1, packet.Length - 1)))
            {
                Int64 session = reader.ReadVarInt64();
                User user;
                if (!_users.TryGetValue((uint)session, out user))   //If we don't know the user for this packet, just ignore the packet
                    return;

                Int64 sequence = reader.ReadVarInt64();

                byte header = 0;
                do
                {
                    header = reader.ReadByte();
                    int length = header & 127;
                    byte[] data = reader.ReadBytes(length);

                    //TODO:: We have a voice packet for this user (data)... do something with it!

                } while ((header & 128) == 0);
            }
        }