Advertisement
Guest User

Original Voice Chat (Unity Audio + Mirror + Facepunch Steamworks)

a guest
Mar 23rd, 2022
56
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. using System;
  2. using Mirror;
  3. using Steamworks;
  4. using System.IO;
  5. using UnityEngine;
  6. using TMPro;
  7.  
  8. public class VoiceChat : NetworkBehaviour
  9. {
  10.     [SerializeField]
  11.     private AudioSource source;
  12.     private MemoryStream output;
  13.     private MemoryStream stream;
  14.     private MemoryStream input;
  15.  
  16.     private int optimalRate;
  17.     private int clipBufferSize;
  18.     private float[] clipBuffer;
  19.  
  20.     private int playbackBuffer;
  21.     private int dataPosition;
  22.     private int dataReceived;
  23.  
  24.     private void Start()
  25.     {
  26.         optimalRate = (int)SteamUser.OptimalSampleRate;
  27.  
  28.         clipBufferSize = optimalRate * 5;
  29.         clipBuffer = new float[clipBufferSize];
  30.  
  31.         stream = new MemoryStream();
  32.         output = new MemoryStream();
  33.         input = new MemoryStream();
  34.        
  35.         // Assign OnAudioread as pcmreader callback
  36.         source.clip = AudioClip.Create("VoiceData", (int)256, 1, (int)optimalRate, true, OnAudioRead, null);
  37.         source.loop = true;
  38.         source.Play();
  39.  
  40.         if(isLocalPlayer) {
  41.             chatGUI.gameObject.SetActive(true);
  42.         }
  43.     }
  44.    
  45.     // User Input: Automatically send data to server in CmdVoice()
  46.     private void Update()
  47.     {
  48.         if(!isLocalPlayer) return;
  49.  
  50.         SteamUser.VoiceRecord = Input.GetKey(KeyCode.V);
  51.  
  52.         if (SteamUser.HasVoiceData)
  53.         {
  54.             int compressedWritten = SteamUser.ReadVoiceData(stream);
  55.             stream.Position = 0;
  56.  
  57.             CmdVoice(new ArraySegment<byte>(stream.GetBuffer(), 0, compressedWritten));
  58.         }
  59.     }
  60.    
  61.     // Executed on Server: Sends voice data to all players
  62.     [Command(channel = 1)]
  63.     public void CmdVoice(ArraySegment<byte> compressed)
  64.     {
  65.         RpcVoiceData(compressed);
  66.     }
  67.  
  68.     /* ### CALLED ON CLIENT WHEN DATA RECIEVED ### */
  69.     //[ClientRpc(channel = 1, includeOwner = false)]
  70.     [ClientRpc(channel = 1)]
  71.     public void RpcVoiceData(ArraySegment<byte> compressed)
  72.     {
  73.         input.Write(compressed.ToArray(), 0, compressed.Count);
  74.         input.Position = 0;
  75.  
  76.         int uncompressedWritten = SteamUser.DecompressVoice(input, compressed.Count, output);
  77.         input.Position = 0;
  78.  
  79.         byte[] outputBuffer = output.GetBuffer();
  80.         WriteToClip(outputBuffer, uncompressedWritten);
  81.         output.Position = 0;
  82.     }
  83.    
  84.     /* ### PCMREADER CALLBACK ### */
  85.     [Client]
  86.     private void OnAudioRead(float[] data)
  87.     {
  88.         for (int i = 0; i < data.Length; ++i)
  89.         {
  90.             // start with silence
  91.             data[i] = 0;
  92.  
  93.             // do I  have anything to play?
  94.             if (playbackBuffer > 0)
  95.             {
  96.                 // current data position playing
  97.                 dataPosition = (dataPosition + 1) % clipBufferSize;
  98.  
  99.                 data[i] = clipBuffer[dataPosition];
  100.  
  101.                 playbackBuffer --;
  102.             }
  103.         }
  104.  
  105.     }
  106.    
  107.     /* ### WRITES NEW AUDIO DATA INTO CLIP BUFFER ### */
  108.     [Client]
  109.     private void WriteToClip(byte[] uncompressed, int iSize)
  110.     {
  111.         for (int i = 0; i < iSize; i += 2)
  112.         {
  113.             // insert converted float to buffer
  114.             float converted = (short)(uncompressed[i] | uncompressed[i + 1] << 8) / 32767.0f;
  115.             clipBuffer[dataReceived] = converted;
  116.  
  117.             // buffer loop
  118.             dataReceived = (dataReceived +1) % clipBufferSize;
  119.  
  120.             playbackBuffer++;
  121.         }
  122.     }
  123.  
  124. }
Advertisement
RAW Paste Data Copied
Advertisement