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: .. code-block:: csharp 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.