Esempio n. 1
0
        internal void PreparePacket(ReadOnlySpan <byte> pcm, ref Memory <byte> target)
        {
            var audioFormat = AudioFormat;

            var packetArray = ArrayPool <byte> .Shared.Rent(Rtp.CalculatePacketSize(audioFormat.SampleCountToSampleSize(audioFormat.CalculateMaximumFrameSize()), SelectedEncryptionMode));

            var packet = packetArray.AsSpan();

            Rtp.EncodeHeader(Sequence, Timestamp, SSRC, packet);
            var opus = packet.Slice(Rtp.HeaderSize, pcm.Length);

            Opus.Encode(pcm, ref opus);

            Sequence++;
            Timestamp += (uint)audioFormat.CalculateFrameSize(audioFormat.CalculateSampleDuration(pcm.Length));

            Span <byte> nonce = new byte[Sodium.NonceSize];

            switch (SelectedEncryptionMode)
            {
            case EncryptionMode.XSalsa20_Poly1305:
                Sodium.GenerateNonce(packet.Slice(0, Rtp.HeaderSize), nonce);
                break;

            case EncryptionMode.XSalsa20_Poly1305_Suffix:
                Sodium.GenerateNonce(nonce);
                break;

            case EncryptionMode.XSalsa20_Poly1305_Lite:
                Sodium.GenerateNonce(Nonce++, nonce);
                break;

            default:
                ArrayPool <byte> .Shared.Return(packetArray);

                throw new Exception("Unsupported encryption mode.");
            }

            Span <byte> encrypted = new byte[Sodium.CalculateTargetSize(opus)];

            Sodium.Encrypt(opus, encrypted, nonce);
            encrypted.CopyTo(packet.Slice(Rtp.HeaderSize));
            packet = packet.Slice(0, Rtp.CalculatePacketSize(encrypted.Length, SelectedEncryptionMode));
            Sodium.AppendNonce(nonce, packet, SelectedEncryptionMode);

            target = target.Slice(0, packet.Length);
            packet.CopyTo(target.Span);
            ArrayPool <byte> .Shared.Return(packetArray);
        }