internal bool PreparePacket(ReadOnlySpan <byte> pcm, out byte[] target, out int length) { target = null; length = 0; if (this.IsDisposed) { return(false); } var audioFormat = this.AudioFormat; var packetArray = ArrayPool <byte> .Shared.Rent(this.Rtp.CalculatePacketSize(audioFormat.SampleCountToSampleSize(audioFormat.CalculateMaximumFrameSize()), this.SelectedEncryptionMode)); var packet = packetArray.AsSpan(); this.Rtp.EncodeHeader(this.Sequence, this.Timestamp, this.SSRC, packet); var opus = packet.Slice(Rtp.HeaderSize, pcm.Length); this.Opus.Encode(pcm, ref opus); this.Sequence++; this.Timestamp += (uint)audioFormat.CalculateFrameSize(audioFormat.CalculateSampleDuration(pcm.Length)); Span <byte> nonce = stackalloc byte[Sodium.NonceSize]; switch (this.SelectedEncryptionMode) { case EncryptionMode.XSalsa20_Poly1305: this.Sodium.GenerateNonce(packet.Slice(0, Rtp.HeaderSize), nonce); break; case EncryptionMode.XSalsa20_Poly1305_Suffix: this.Sodium.GenerateNonce(nonce); break; case EncryptionMode.XSalsa20_Poly1305_Lite: this.Sodium.GenerateNonce(this.Nonce++, nonce); break; default: ArrayPool <byte> .Shared.Return(packetArray); throw new Exception("Unsupported encryption mode."); } Span <byte> encrypted = stackalloc byte[Sodium.CalculateTargetSize(opus)]; this.Sodium.Encrypt(opus, encrypted, nonce); encrypted.CopyTo(packet.Slice(Rtp.HeaderSize)); packet = packet.Slice(0, this.Rtp.CalculatePacketSize(encrypted.Length, this.SelectedEncryptionMode)); this.Sodium.AppendNonce(nonce, packet, this.SelectedEncryptionMode); target = packetArray; length = packet.Length; return(true); }
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); }