Voice Chat

Overview

Voice chat is disabled by default in UCNetwork, but the underlying infrastructure fully supports it. With a few modifications, you can enable real-time, low-latency voice communication between players.

UCNetwork’s voice chat supports both proximity voice (3D positional audio) and radio communication (direct, non-positional). It uses multiple threads to handle compression and decompression in parallel, efficiently utilizing the CPU.

UCNetwork’s voice chat integration was originally developed using concepts from the open-source voice chat library by FHolm.

Voice Chat: A Primer

Voice chat works by continuously capturing a player’s microphone input, compressing it to reduce bandwidth, transmitting it across the network, and reconstructing and playing it back on other clients with appropriate timing and spatialization.

When a player speaks:

  1. The microphone captures a stream of raw audio samples.

  2. The samples are encoded with a codec (e.g., Opus, Speex, or A-Law) to create small, bandwidth-efficient packets.

  3. The packets are serialized and sent over the network using MessageType.VoiceData.

  4. Other clients receive, decode, and buffer the packets.

  5. The decoded audio is played through an AudioSource at the correct spatial position.

In games that use positional audio, the decoded sound is positioned in 3D space based on the speaker’s in-game location and orientation, creating the illusion that the voice originates from that character. In Unity, this is done by creating temporary or pooled AudioSource objects and positioning them according to the networked player’s transform.

Getting Started

To enable and configure voice chat in UCNetwork:

  1. Download the voice chat package Download VoiceChat.zip and extract it into your Assets/Scripts folder.

  2. Enable VoiceData message handling In ClientNetwork.HandleMessage_Data, uncomment the logic that processes MessageType.VoiceData messages.

  3. Add a VoiceChatRecorder Attach a VoiceChatRecorder component to a GameObject in your scene. This object captures microphone input, encodes it, and broadcasts it to the network.

  4. Send audio packets In VoiceChatRecorder.BroadcastVoiceData, after compressing a sample, call:

    clientNetwork.SendVoiceData(aNetObjId, aCompressionType, aDataLength, aData, aVoiceDataId, aChannel);
    
  5. Configure remote playback In your ClientNetwork component, assign the Remote Voice Chat Container and Remote Voice Chat Prefab (a prefab with a

    VoiceChatPlayer component for receiving and playing audio)

After completing these steps, verify that microphone data is: - Recorded - Compressed and transmitted over the network - Received by other clients - Decompressed and played back spatially through an AudioSource

Voice Chat Files

Below is a breakdown of each file in the voice chat module and what it does.

Editor/VoiceChatRecorderEditor.cs Custom inspector for VoiceChatRecorder. At runtime, shows available devices, start/stop recording buttons, and live status indicators.

Editor/VoiceChatSettingsEditor.cs Custom inspector for VoiceChatSettings. Allows codec/preset selection, toggling local debug, and displays derived values (frequency, sample size).

Libs/Exocortex.DSP.cs Embedded DSP/FFT utilities used for analyzing audio frequencies (for example, auto-detecting speech).

Libs/NAudio.cs Minimal A-Law utilities (decoder, lookup tables) extracted from NAudio. Used for encoding/decoding A-Law audio without requiring the full library.

VoiceChatChannel.cs Enum for voice chat routing (Proximity, Radio, Global). Used to label or route packets by channel.

VoiceChatCircularBuffer.cs Efficient ring buffer used for enqueue/dequeue of audio samples without allocations. Provides smooth playback even under jitter.

VoiceChatCompression.cs Enum listing available compression strategies (A-Law, A-Law + Zlib, Speex). Some variants may be commented out depending on your codec setup.

VoiceChatPacket.cs Lightweight model for a single voice packet. Stores codec type, payload length, compressed byte array, and sender NetworkId.

VoiceChatPlayer.cs Component for audio playback. Receives compressed voice packets, decodes them, buffers for smooth playback, and outputs to an AudioSource. Manages playback delay to prevent underruns.

VoiceChatPool.cs Object pool for reusing audio buffers (short[] and float[]), minimizing garbage collection.

VoiceChatPreset.cs Enum of configuration presets (e.g., Speex_8K, Alaw_16k) that map to codec settings in VoiceChatSettings.

VoiceChatRecorder.cs Captures microphone input, slices into frames, compresses each frame, and sends it via the network. Supports push-to-talk, toggle-to-talk, and optional voice activity detection (FFT-based).

VoiceChatSettings.cs Singleton for global voice configuration: selected preset, codec, frequency, and sample size. Includes a LocalDebug flag for local loopback testing.

VoiceChatUtils.cs Codec utilities for A-Law and Speex compression/decompression, optional Zlib compression, and type conversions between float and short arrays.

Next Steps

Once you’ve confirmed the default system works:

  • Adjust settings for push-to-talk controls in VoiceChatRecorder.

  • Experiment with proximity distance (attenuation range).

  • Consider extending the VoiceChatChannel system for private groups, teams, or radio networks.

  • Test across real network conditions to tune codec and buffer sizes for latency vs. quality.

Summary

  • Voice chat is fully supported but disabled by default.

  • Enable MessageType.VoiceData handling in ClientNetwork.

  • Add a VoiceChatRecorder to capture and send audio.

  • Add a VoiceChatPlayer prefab to receive and play voice data.

  • Customize settings via VoiceChatSettings and choose codecs/presets as needed.